home *** CD-ROM | disk | FTP | other *** search
- /*
- Support routines for the CRT unit
-
- Copyright (C) 1998-2001 Free Software Foundation, Inc.
-
- Author: Frank Heckenbach <frank@pascal.gnu.de>
-
- This file is part of GNU Pascal.
-
- GNU Pascal is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GNU Pascal is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU Pascal; see the file COPYING. If not, write to the
- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-
- As a special exception, if you link this file with files compiled
- with a GNU compiler to produce an executable, this does not cause
- the resulting executable to be covered by the GNU General Public
- License. This exception does not however invalidate any other
- reasons why the executable file might be covered by the GNU General
- Public License.
- */
-
- /* Prevent stdlib.h from declaring a beep() function which would
- conflict with PDCurses' one */
- #ifdef __MINGW32__
- #undef _NO_OLDNAMES
- #define _NO_OLDNAMES 1
- #endif
-
- /* @@ Request old behaviour of signal handlers, in particular
- non-restarting system calls */
- #ifdef linux
- #undef _XOPEN_SOURCE
- #define _XOPEN_SOURCE 1
- #endif
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <ctype.h>
- #include <errno.h>
- #include <signal.h>
- #include "crtc.h"
-
- int crt_get_input_fd (void);
- int crt_get_output_fd (void);
-
- extern int crt_input_fd, crt_output_fd;
-
- #ifdef USE_PDCURSES
-
- #ifdef XCURSES
-
- #include <xcurses.h>
- #include <xpanel.h>
- char *XCursesProgramName;
-
- /* Try to shut down cleanly when X11 is shut down */
- #include <setjmp.h>
- static jmp_buf crt_ShutDownJump;
- static int crt_ShutDownJumpActive = FALSE;
-
- #else
-
- #include <curses.h>
- #include <panel.h>
-
- #endif
-
- #define REVERSE_WORKS FALSE
- #define INVIS_WORKS TRUE
- #define HAVE_RAW_OUTPUT
-
- /* This is undocumented, but there doesn't seem to be another way! */
- #define SETCURSOR(x,y) wmove (curscr, y, x)
-
- int crt_get_input_fd ()
- {
- return PDC_get_input_fd ();
- }
-
- #ifdef XCURSES
-
- int crt_get_output_fd ()
- {
- return - 1;
- }
-
- /* We don't have to clear the terminal since XCurses programs run in
- their own windows, anyway. */
- static void crt_clear_terminal ()
- {
- }
-
- #else
-
- int crt_get_output_fd ()
- {
- return crt_output_fd >= 0 ? crt_output_fd : fileno (stdout);
- }
-
- extern int PDC_clr_scrn (WINDOW *win);
-
- static void crt_clear_terminal ()
- {
- PDC_clr_scrn (stdscr);
- }
- #endif
- #endif
-
- #ifdef USE_NCURSES
- #include <ncurses.h>
- #if NCURSES_VERSION_MAJOR < 5
- #warning The CRT unit needs ncurses version 5.0 or newer because older
- #warning versions contain a bug that severely affects CRT programs.
- #endif
- #include <panel.h>
- #include <term.h>
- #define REVERSE_WORKS TRUE
- #define INVIS_WORKS FALSE
- #undef HAVE_RAW_OUTPUT
-
- /* From dialog-0.9 */
- #define isprivate(s) ((s) != 0 && strstr (s, "\033[?") != 0)
-
- static char *crt_save_enter_ca_mode = NULL, *crt_save_exit_ca_mode = NULL;
-
- /* This is undocumented, but there doesn't seem to be another way! */
- #define SETCURSOR(x,y) wmove (newscr, y, x)
-
- int crt_get_input_fd ()
- {
- return crt_input_fd >= 0 ? crt_input_fd : fileno (stdin);
- }
-
- int crt_get_output_fd ()
- {
- return crt_output_fd >= 0 ? crt_output_fd : fileno (stdout);
- }
-
- static int putch (int c)
- {
- char ch = c;
- return write (crt_get_output_fd (), &ch, sizeof (ch)) >= 0 ? c : EOF;
- }
-
- static void crt_clear_terminal ()
- {
- tputs (clear_screen, lines > 0 ? lines : 1, putch);
- fflush (stdout);
- }
-
- static WINDOW *resize_window (WINDOW *w, int new_lines, int new_columns)
- {
- wresize (w, new_lines, new_columns);
- return w;
- }
- #endif
-
- #ifndef A_ALTCHARSET
- #define A_ALTCHARSET 0
- #endif
-
- typedef unsigned char Boolean;
- typedef unsigned int TKey;
- typedef unsigned char Char;
- typedef unsigned char TTextAttr;
- typedef enum { CursorIgnored, CursorHidden, CursorNormal, CursorFat, CursorBlock } TCursorShape;
- typedef enum { UpdateNever, UpdateWaitInput, UpdateInput, UpdateRegularly, UpdateAlways } TCRTUpdate;
- typedef struct { int x, y; } TPoint;
-
- typedef struct
- {
- Char Ch;
- TTextAttr Attr;
- Boolean PCCharSet;
- } TCharAttr;
-
- typedef struct
- {
- int curses_key;
- Char crt_key;
- } TKeyTable;
-
- typedef struct TPanelData
- {
- struct TPanelData *Next;
- WINDOW *w;
- PANEL *panel;
- Boolean BoundToBackground, Hidden, ScrollState, PCCharSet, UseControlChars;
- TCursorShape CursorShape;
- int WindXMin, WindXMax, WindYMin, WindYMax;
- unsigned int LastWindMin, LastWindMax;
- TTextAttr TextAttr;
- } TPanelData;
- typedef TPanelData *TPanel;
-
- extern int crt_VirtualShiftState;
- extern char *crt_term;
- extern unsigned int crt_LastMode, crt_WindMin, crt_WindMax;
- extern Boolean crt_CheckBreak, crt_CheckEOF, crt_VisualBell, crt_IsMonochrome, crt_terminal_no_crt, crt_clearflag;
- extern TTextAttr crt_TextAttr, crt_NormAttr;
- extern void (*crt_auto_init_proc) (void);
- extern TPoint crt_ScreenSize, crt_cursor_pos;
-
- /* modified by signal handlers */
- extern volatile Boolean crt_Signaled;
- static volatile Boolean crt_screen_size_changed = FALSE, crt_ShutDown = FALSE;
- static volatile TKey crt_unget_key_buf = 0;
-
- extern char *crt_get_program_name (void);
- extern char **crt_get_c_environment (void);
- extern void crt_dotextmodecommand (int, int);
- extern void crt_registerrestoreterminal (void);
- extern void crt_signal_handler (TKey sig);
- extern void crt_fatal (int) __attribute__((noreturn));
- extern void _p_SetReturnAddress (void *);
- extern void _p_RestoreReturnAddress (void);
-
- #define SAVE_RETURN_ADDRESS _p_SetReturnAddress (__builtin_return_address (0))
- #define RESTORE_RETURN_ADDRESS _p_RestoreReturnAddress ()
- #define DO_RETURN_ADDRESS(stmt) \
- do \
- { \
- SAVE_RETURN_ADDRESS; \
- stmt; \
- RESTORE_RETURN_ADDRESS; \
- } \
- while (0)
-
- static void crt_refresh (void);
- void crt_check_winchanged (void);
- int crt_default_save_restore_screen (Boolean Restore);
-
- #define DO_CRT_CHECK_WINCHANGED DO_RETURN_ADDRESS (crt_check_winchanged ())
-
- /*
- There are a few features that cannot be implemented in a portable
- way, but rather for different systems individually. There are
- defaults for systems where they are not specially supported, see the
- comment in crt.pas. The following table lists these items, how to
- check them in CRTDemo, and how to implement them on a new system.
- Implementations for new systems should go into separate files,
- included with appropriate ifdefs below this comment. Prototypes of
- the functions to be implemented can be found there.
-
- - Playing sounds with Sound and NoSound. In CRTDemo, this can be
- checked with the `Sound check' in the `Various checks' window.
-
- To support them on a system, define HAVE_CRT_SOUND and implement
- the functions crt_sound() (start playing a sound of the given
- frequency, until the next crt_sound() or crt_nosound() call), and
- crt_nosound() (stop playing any sound).
-
- - Getting the keyboard shift state. In CRTDemo, this can be checked
- in the `Modifier Keys' window.
-
- By default, this is supported on PDCurses platforms. To support
- this on another system (or to override the PDCurses version),
- define HAVE_CRT_GETSHIFTSTATE and implement the function
- crt_getshiftstate() (return the keyboard shift state as a
- combination of the shFoo constants, ORed with the value of the
- variable crt_VirtualShiftState).
-
- - Changing the screen size with TextMode. In CRTDemo, this can be
- checked by changing `Screen columns' and/or `Screen lines' in the
- `Status' window.
-
- By default, this is supported on PDCurses platforms except X11
- (and changing the number of columns doesn't work everywhere). For
- ncurses platforms, the code tries to change the size via an
- external executable. To support this on another system (or to
- override the PDCurses version), define HAVE_CRT_GETSHIFTSTATE and
- implement the function crt_change_screen_size() (change the screen
- size to the given size).
-
- - Saving and restoring the original screen contents (e.g., after and
- before starting a child program.
-
- By default, this is supported if the terminal supports it via
- smcup/rmcup (as, e.g., xterms do), and it's not necessary on
- XCurses where the program runs in its own window, anyway. To
- support this on another system, define
- HAVE_CRT_SAVE_RESTORE_SCREEN and implement the function
- crt_save_restore_screen() (save or restore the screen contents).
-
- - Catching INT (Ctrl-C) and/or TERM, HUP and under XCurses also PIPE
- signals to let them be treated by CRT, dependent on CheckBreak. In
- CRTDemo, this can be checked by verifying that the program reacts
- to interrupt (Ctrl-C) keys (and if applicable, suspend (Ctrl-Z)
- keys as well as to being killed with INT, TERM, HUP signals, or
- for XCurses, shutting down X11) appropriately, depending on the
- setting of `Break checking' in the `Status' window. Also, catching
- WINCH signals. In CRTDemo, this can by checked by resizing the
- terminal or window by external means and verifying that the
- `Status' window recognizes the new screen size.
-
- By default, handlers are implemented for any of these signals
- which are actually defined on the system. These handlers have been
- found working on all systems tested so far, so usually you won't
- have to worry about them. If you want to implement different
- handlers, define HAVE_CRT_SIGNAL_HANDLERS, and implement the
- function crt_init_signals() (install the signal handlers at the
- start of the program). The signal handlers, in turn, should call
- crt_signal_handler() whenever an INT, TERM, HUP or similar signal
- or SIGPIPE under XCurses is received, giving it as an argument a
- pseudo key code for the signal, and make sure that the program is
- not aborted by the signal. Reading a character from the curses
- window should be interrupted by the signal (which ought to happen
- by default), in order for the program to receive the pseudo key
- immediately. The signal handler for WINCH should set
- crt_screen_size_changed and crt_Signaled, and call any previously
- installed signal handler (e.g. ncurses' one).
- */
- void crt_sound (unsigned Hz);
- void crt_nosound (void);
- int crt_getshiftstate (void);
- static void crt_change_screen_size (int Columns, int Lines);
- static int crt_save_restore_screen (Boolean Restore);
- static void crt_init_signals (void);
-
- #if defined (__linux__) && defined (__i386__) && !defined (XCURSES)
- #include "crtlinux386.h"
- #elif defined (DJGPP)
- #include "crtdjgpp.h"
- #endif
-
- #define MAXLENGTH 4096
-
- static TCRTUpdate crt_update_level = UpdateWaitInput;
- static TCursorShape crt_last_shape = - 1;
- static Char crt_fkey_buf = 0, crt_line_buf [MAXLENGTH], *crt_line_buf_pos = crt_line_buf;
- static size_t crt_line_buf_count = 0;
- static TPanel crt_ActivePanel = NULL, crt_PanelList = NULL;
- static PANEL *crt_SimulateBlockCursorPanel = NULL;
- static WINDOW *crt_dummy_pad = NULL;
- static int crt_inited = 0, crt_key_buf = 0,
- crt_refresh_inhibit = 0, crt_refresh_flag = 0,
- crt_save_previous_screen_flag = - 2,
- crt_colors [8] = { COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN,
- COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE };
- static chtype crt_attrs [8] [8], crt_monoattrs [8] [8];
- static Boolean crt_ColorFlag = FALSE,
- crt_HasColors = FALSE,
- crt_screen_restored = FALSE,
- crt_linux_console = FALSE,
- crt_LastCheckBreak = - 1,
- crt_pending_refresh = FALSE,
- crt_PCCharSet = FALSE,
- crt_UpdateLevelChanged = FALSE,
- crt_SimulateBlockCursorActive = FALSE;
-
- #define KEY_HUP (KEY_MAX + 1)
- #ifndef KEY_RESIZE
- #define KEY_RESIZE (KEY_MAX + 2)
- #endif
-
- #define FKEY1 KEY_F (1)
- #define FKEYSH1 KEY_F (13)
- #define FKEYCTRL1 KEY_F (25)
- #define FKEYALT1 KEY_F (37)
-
- static TKeyTable KeyTable [] =
- {
- { KEY_BACKSPACE, chBkSp },
- { '\b', chBkSp },
- { 127, chBkSp },
- { KEY_SUSPEND, 26 },
- { '\n', chCR },
- #ifdef USE_PDCURSES
- { '\r', chCR },
- { PADSTAR, '*' },
- { PADMINUS, '-' },
- { PADPLUS, '+' },
- { CTL_ENTER, chLF },
- { CTL_PADENTER, chLF },
- { CTL_PADSTAR, chLF },
- { CTL_PADMINUS, chCR },
- { CTL_PADPLUS, 11 },
- #else
- { '\r', chLF },
- #endif
- { 0, 0 }
- };
-
- static TKeyTable FKeyTable [] =
- {
- { KEY_RESIZE, ksScreenSizeChanged },
- { KEY_BTAB, ksShTab },
- { KEY_LEFT, ksLeft },
- { KEY_RIGHT, ksRight },
- { KEY_UP, ksUp },
- { KEY_DOWN, ksDown },
- { KEY_A3, ksPgUp },
- { KEY_PPAGE, ksPgUp },
- { KEY_C3, ksPgDn },
- { KEY_NPAGE, ksPgDn },
- { KEY_A1, ksHome },
- { KEY_HOME, ksHome },
- { KEY_C1, ksEnd },
- { KEY_END, ksEnd },
- { KEY_IC, ksIns },
- { KEY_DC, ksDel },
- { KEY_B2, ksCenter },
- { KEY_CANCEL, ksCancel },
- { KEY_COPY, ksCopy },
- { KEY_UNDO, ksUndo },
- { KEY_REDO, ksRedo },
- { KEY_OPEN, ksOpen },
- { KEY_CLOSE, ksClose },
- { KEY_COMMAND, ksCommand },
- { KEY_CREATE, ksCreate },
- { KEY_EXIT, ksExit },
- { KEY_FIND, ksFind },
- { KEY_HELP, ksHelp },
- { KEY_MARK, ksMark },
- { KEY_MESSAGE, ksMessage },
- { KEY_MOVE, ksMove },
- { KEY_NEXT, ksNext },
- { KEY_PREVIOUS, ksPrevious },
- { KEY_OPTIONS, ksOptions },
- { KEY_REFERENCE, ksReference },
- { KEY_REFRESH, ksRefresh },
- { KEY_REPLACE, ksReplace },
- { KEY_RESTART, ksRestart },
- { KEY_SUSPEND, ksSuspend },
- { KEY_RESUME, ksResume },
- { KEY_SAVE, ksSave },
- #ifdef XCURSES
- /* XCurses returns these for *shifted* keys (which is not wrong :-).
- However, we don't have key codes for shifted keys, but we can get
- the shift state via crt_getshiftstate(). Control-key combinations
- are obtained using crt_getshiftstate(). */
- { KEY_SLEFT, ksLeft },
- { KEY_SRIGHT, ksRight },
- { KEY_SHOME, ksHome },
- { KEY_SEND, ksEnd },
- { KEY_SDC, ksDel },
- { KEY_SIC, ksIns },
- #else
- { KEY_SLEFT, ksCtrlLeft },
- { KEY_SRIGHT, ksCtrlRight },
- { KEY_SHOME, ksCtrlHome },
- { KEY_SEND, ksCtrlEnd },
- { KEY_SDC, ksCtrlDel },
- { KEY_SIC, ksCtrlIns },
- #endif
- #ifdef USE_PDCURSES
- { CTL_TAB, ksCtrlTab },
- { ALT_TAB, ksAltTab },
- { KEY_A2, ksUp },
- { KEY_B1, ksLeft },
- { KEY_B3, ksRight },
- { KEY_C2, ksDown },
- { CTL_LEFT, ksCtrlLeft },
- { CTL_RIGHT, ksCtrlRight },
- { CTL_UP, ksCtrlUp },
- { CTL_DOWN, ksCtrlDown },
- { CTL_PGUP, ksCtrlPgUp },
- { CTL_PGDN, ksCtrlPgDn },
- { CTL_HOME, ksCtrlHome },
- { CTL_END, ksCtrlEnd },
- { CTL_INS, ksCtrlIns },
- { CTL_DEL, ksCtrlDel },
- { CTL_PADSTOP, ksCtrlDel },
- { CTL_PADCENTER, ksCtrlCentr },
- { ALT_LEFT, ksAltLeft },
- { ALT_RIGHT, ksAltRight },
- { ALT_UP, ksAltUp },
- { ALT_DOWN, ksAltDown },
- { ALT_PGUP, ksAltPgUp },
- { ALT_PGDN, ksAltPgDn },
- { ALT_HOME, ksAltHome },
- { ALT_END, ksAltEnd },
- { ALT_INS, ksAltIns },
- { ALT_DEL, ksAltDel },
- { ALT_ENTER, ksAltEnter },
- { ALT_PADENTER, ksAltEnter },
- { ALT_PADSTAR, ksAltPStar },
- { ALT_PADMINUS, ksAltPMinus },
- { ALT_PADPLUS, ksAltPPlus },
- { ALT_ESC, ksAltEsc },
- { ALT_BKSP, ksAltBkSp },
- { ALT_MINUS, ksAltMinus },
- { ALT_EQUAL, ksAltEqual },
- { ALT_LBRACKET, ksAltLBrack },
- { ALT_RBRACKET, ksAltRBrack },
- { ALT_SEMICOLON, ksAltSemic },
- { ALT_FQUOTE, ksAltFQuote },
- { ALT_BQUOTE, ksAltBQuote },
- { ALT_COMMA, ksAltComma },
- { ALT_STOP, ksAltStop },
- { ALT_FSLASH, ksAltFSlash },
- { ALT_BSLASH, ksAltBSlash },
- { ALT_0, ksAlt0 },
- { ALT_1, ksAlt1 },
- { ALT_2, ksAlt2 },
- { ALT_3, ksAlt3 },
- { ALT_4, ksAlt4 },
- { ALT_5, ksAlt5 },
- { ALT_6, ksAlt6 },
- { ALT_7, ksAlt7 },
- { ALT_8, ksAlt8 },
- { ALT_9, ksAlt9 },
- { ALT_A, ksAltA },
- { ALT_B, ksAltB },
- { ALT_C, ksAltC },
- { ALT_D, ksAltD },
- { ALT_E, ksAltE },
- { ALT_F, ksAltF },
- { ALT_G, ksAltG },
- { ALT_H, ksAltH },
- { ALT_I, ksAltI },
- { ALT_J, ksAltJ },
- { ALT_K, ksAltK },
- { ALT_L, ksAltL },
- { ALT_M, ksAltM },
- { ALT_N, ksAltN },
- { ALT_O, ksAltO },
- { ALT_P, ksAltP },
- { ALT_Q, ksAltQ },
- { ALT_R, ksAltR },
- { ALT_S, ksAltS },
- { ALT_T, ksAltT },
- { ALT_U, ksAltU },
- { ALT_V, ksAltV },
- { ALT_W, ksAltW },
- { ALT_X, ksAltX },
- { ALT_Y, ksAltY },
- { ALT_Z, ksAltZ },
- #endif
- { FKEYSH1 + 10, ksShF11 },
- { FKEYSH1 + 11, ksShF12 },
- { FKEYCTRL1 + 10, ksCtrlF11 },
- { FKEYCTRL1 + 11, ksCtrlF12 },
- { FKEYALT1 + 10, ksAltF11 },
- { FKEYALT1 + 11, ksAltF12 },
- { 0, ksUnknown }
- };
-
- static TKeyTable ShiftKeyTable [] =
- {
- { chTab, ksShTab },
- { 0, 0 }
- };
-
- static TKeyTable ShiftFKeyTable [] =
- {
- { ksIns, ksShIns },
- { ksDel, ksShDel },
- { 0, 0 }
- };
-
- static TKeyTable CtrlFKeyTable [] =
- {
- { ksLeft, ksCtrlLeft },
- { ksRight, ksCtrlRight },
- { ksUp, ksCtrlUp },
- { ksDown, ksCtrlDown },
- { ksPgUp, ksCtrlPgUp },
- { ksPgDn, ksCtrlPgDn },
- { ksHome, ksCtrlHome },
- { ksEnd, ksCtrlEnd },
- { ksIns, ksCtrlIns },
- { ksDel, ksCtrlDel },
- { ksCenter, ksCtrlCentr },
- { ksF1, ksCtrlF1 },
- { ksF2, ksCtrlF2 },
- { ksF3, ksCtrlF3 },
- { ksF4, ksCtrlF4 },
- { ksF5, ksCtrlF5 },
- { ksF6, ksCtrlF6 },
- { ksF7, ksCtrlF7 },
- { ksF8, ksCtrlF8 },
- { ksF9, ksCtrlF9 },
- { ksF10, ksCtrlF10 },
- { ksF11, ksCtrlF11 },
- { ksF12, ksCtrlF12 },
- { 0, 0 }
- };
-
- static TKeyTable AltFKeyTable [] =
- {
- { ksLeft, ksAltLeft },
- { ksRight, ksAltRight },
- { ksUp, ksAltUp },
- { ksDown, ksAltDown },
- { ksPgUp, ksAltPgUp },
- { ksPgDn, ksAltPgDn },
- { ksHome, ksAltHome },
- { ksEnd, ksAltEnd },
- { ksIns, ksAltIns },
- { ksDel, ksAltDel },
- { 0, 0 }
- };
-
- static TKeyTable AltKeyTable [] =
- {
- { ' ', ksAltSpace },
- { chLF, ksAltEnter },
- { chCR, ksAltEnter },
- { 0, 0 }
- };
-
- static TKeyTable AltGrKeyTable [] =
- {
- { '0', ksAltGr0 },
- { '1', ksAltGr1 },
- { '2', ksAltGr2 },
- { '3', ksAltGr3 },
- { '4', ksAltGr4 },
- { '5', ksAltGr5 },
- { '6', ksAltGr6 },
- { '7', ksAltGr7 },
- { '8', ksAltGr8 },
- { '9', ksAltGr9 },
- { 'A', ksAltGrA },
- { 'B', ksAltGrB },
- { 'C', ksAltGrC },
- { 'D', ksAltGrD },
- { 'E', ksAltGrE },
- { 'F', ksAltGrF },
- { 'G', ksAltGrG },
- { 'H', ksAltGrH },
- { 'I', ksAltGrI },
- { 'J', ksAltGrJ },
- { 'K', ksAltGrK },
- { 'L', ksAltGrL },
- { 'M', ksAltGrM },
- { 'N', ksAltGrN },
- { 'O', ksAltGrO },
- { 'P', ksAltGrP },
- { 'Q', ksAltGrQ },
- { 'R', ksAltGrR },
- { 'S', ksAltGrS },
- { 'T', ksAltGrT },
- { 'U', ksAltGrU },
- { 'V', ksAltGrV },
- { 'W', ksAltGrW },
- { 'X', ksAltGrX },
- { 'Y', ksAltGrY },
- { 'Z', ksAltGrZ },
- #ifdef USE_PDCURSES
- { ALT_0, ksAltGr0 },
- { ALT_1, ksAltGr1 },
- { ALT_2, ksAltGr2 },
- { ALT_3, ksAltGr3 },
- { ALT_4, ksAltGr4 },
- { ALT_5, ksAltGr5 },
- { ALT_6, ksAltGr6 },
- { ALT_7, ksAltGr7 },
- { ALT_8, ksAltGr8 },
- { ALT_9, ksAltGr9 },
- { ALT_A, ksAltGrA },
- { ALT_B, ksAltGrB },
- { ALT_C, ksAltGrC },
- { ALT_D, ksAltGrD },
- { ALT_E, ksAltGrE },
- { ALT_F, ksAltGrF },
- { ALT_G, ksAltGrG },
- { ALT_H, ksAltGrH },
- { ALT_I, ksAltGrI },
- { ALT_J, ksAltGrJ },
- { ALT_K, ksAltGrK },
- { ALT_L, ksAltGrL },
- { ALT_M, ksAltGrM },
- { ALT_N, ksAltGrN },
- { ALT_O, ksAltGrO },
- { ALT_P, ksAltGrP },
- { ALT_Q, ksAltGrQ },
- { ALT_R, ksAltGrR },
- { ALT_S, ksAltGrS },
- { ALT_T, ksAltGrT },
- { ALT_U, ksAltGrU },
- { ALT_V, ksAltGrV },
- { ALT_W, ksAltGrW },
- { ALT_X, ksAltGrX },
- { ALT_Y, ksAltGrY },
- { ALT_Z, ksAltGrZ },
- #endif
- { 0, 0 }
- };
-
- static TKeyTable ExtraKeyTable [] =
- {
- { '0', ksExtra0 },
- { '1', ksExtra1 },
- { '2', ksExtra2 },
- { '3', ksExtra3 },
- { '4', ksExtra4 },
- { '5', ksExtra5 },
- { '6', ksExtra6 },
- { '7', ksExtra7 },
- { '8', ksExtra8 },
- { '9', ksExtra9 },
- { 'A', ksExtraA },
- { 'B', ksExtraB },
- { 'C', ksExtraC },
- { 'D', ksExtraD },
- { 'E', ksExtraE },
- { 'F', ksExtraF },
- { 'G', ksExtraG },
- { 'H', ksExtraH },
- { 'I', ksExtraI },
- { 'J', ksExtraJ },
- { 'K', ksExtraK },
- { 'L', ksExtraL },
- { 'M', ksExtraM },
- { 'N', ksExtraN },
- { 'O', ksExtraO },
- { 'P', ksExtraP },
- { 'Q', ksExtraQ },
- { 'R', ksExtraR },
- { 'S', ksExtraS },
- { 'T', ksExtraT },
- { 'U', ksExtraU },
- { 'V', ksExtraV },
- { 'W', ksExtraW },
- { 'X', ksExtraX },
- { 'Y', ksExtraY },
- { 'Z', ksExtraZ },
- { 0, 0 }
- };
-
- static TKeyTable EscKeyTable [] =
- {
- { KEY_BACKSPACE, ksAltBkSp },
- { chBkSp, ksAltBkSp },
- { chTab, ksAltTab },
- { chLF, ksAltEnter },
- { chCR, ksAltEnter },
- { chEsc, ksAltEsc },
- { ' ', ksAltSpace },
- { '-', ksAltMinus },
- { '=', ksAltEqual },
- { '[', ksAltLBrack },
- { ']', ksAltRBrack },
- { ';', ksAltSemic },
- { '\'', ksAltFQuote },
- { '`', ksAltBQuote },
- { ',', ksAltComma },
- { '.', ksAltStop },
- { '/', ksAltFSlash },
- { '\\', ksAltBSlash },
- { 'A', ksAltA },
- { 'B', ksAltB },
- { 'C', ksAltC },
- { 'D', ksAltD },
- { 'E', ksAltE },
- { 'F', ksAltF },
- { 'G', ksAltG },
- { 'H', ksAltH },
- { 'I', ksAltI },
- { 'J', ksAltJ },
- { 'K', ksAltK },
- { 'L', ksAltL },
- { 'M', ksAltM },
- { 'N', ksAltN },
- { 'O', ksAltO },
- { 'P', ksAltP },
- { 'Q', ksAltQ },
- { 'R', ksAltR },
- { 'S', ksAltS },
- { 'T', ksAltT },
- { 'U', ksAltU },
- { 'V', ksAltV },
- { 'W', ksAltW },
- { 'X', ksAltX },
- { 'Y', ksAltY },
- { 'Z', ksAltZ },
- { '0', ksAlt0 },
- { '1', ksAlt1 },
- { '2', ksAlt2 },
- { '3', ksAlt3 },
- { '4', ksAlt4 },
- { '5', ksAlt5 },
- { '6', ksAlt6 },
- { '7', ksAlt7 },
- { '8', ksAlt8 },
- { '9', ksAlt9 },
- { 0, 0 }
- };
-
- #if !defined (USE_PDCURSES) || defined (XCURSES)
- static chtype chars_0_31 [32] =
- {
- ' ', 'O', 'O', '%', 0, '#', '*', 'o', 'o', 'o', 'o', '/', '+', 'd', 'A', '*',
- 0, 0, 0, '!', '#', '$', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- static chtype chars_128_255 [128] =
- {
- 'C', 'u', 'e', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'i', 'i', 'i', 'A', 'A',
- 'E', 'a', 'A', 'o', 'o', 'o', 'u', 'u', 'y', 'O', 'U', 'C', 0, 'Y', 'P', 'f',
- 'a', 'i', 'o', 'u', 'n', 'N', 0, 0, '?', 0, 0, '/', '/', '!', 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 'a', 'B', 'T', 0, 'E', 'o', 'u', 't', 'O', 'O', 'O', 'O', 'o', 'o', 'E', 'A',
- '=', 0, 0, 0, '/', '/', '%', '=', 0, '.', '.', 'V', 'n', '2', 0, ' '
- };
- #endif
-
- #ifndef HAVE_CRT_SETTEXTMODE
- static void crt_change_screen_size (int Columns, int Lines)
- {
- (void) Columns;
- (void) Lines;
- #ifdef USE_PDCURSES
- #ifdef XCURSES
- /* Don't call resize_term() here -- leads to segfaults (PDCurses 2.4beta.22-May-99) */
- #else
- resize_term (Lines, Columns);
- resize_term (Lines, Columns); /* @@ does not always work the first time -- DJGPP bug? */
- crt_screen_size_changed = TRUE;
- #endif
- #endif
- #ifdef USE_NCURSES
- crt_dotextmodecommand (Columns, Lines);
- if (!crt_Signaled)
- napms (1000); /* give the kernel some time to change the size of
- all consoles -- a SIGWINCH will interrupt this */
- #endif
- }
- #endif
-
- /* Return value:
- 1 : available
- 0 : not available
- -1 : unknown until ncurses is initialized
- Values of crt_save_previous_screen_flag are the same plus:
- -2 : not requested */
- int crt_default_save_restore_screen (Boolean Restore)
- {
- (void) Restore;
- /* The smcup/rmcup support is implicit in ncurses. */
- #ifdef USE_NCURSES
- /* Before ncurses is initialized, exit_ca_mode may be undefined
- (not NULL, but a macro dereferencing NULL) */
- if (!crt_inited)
- return -1;
- return isprivate (Restore ? exit_ca_mode : enter_ca_mode);
- #elif defined (XCURSES)
- return 1;
- #else
- return 0;
- #endif
- }
-
- #ifndef HAVE_CRT_SAVE_RESTORE_SCREEN
- static int crt_save_restore_screen (Boolean Restore)
- {
- return crt_default_save_restore_screen (Restore);
- }
- #endif
-
- #ifndef HAVE_CRT_GETSHIFTSTATE
- int crt_getshiftstate ()
- {
- int state = crt_VirtualShiftState;
- #ifdef USE_PDCURSES
- unsigned long modifiers;
- DO_CRT_CHECK_WINCHANGED;
- modifiers = PDC_get_key_modifiers ();
- if (modifiers & PDC_KEY_MODIFIER_SHIFT ) state |= shShift;
- if (modifiers & PDC_KEY_MODIFIER_CONTROL) state |= shCtrl;
- if (modifiers & PDC_KEY_MODIFIER_ALT ) state |= shAlt;
- #ifdef XCURSES
- if (modifiers & PDC_KEY_MODIFIER_MOD4 ) state |= shExtra;
- if (modifiers & PDC_KEY_MODIFIER_MOD3 ) state = shAltGr;
- #else
- if (modifiers & PDC_KEY_MODIFIER_NUMLOCK) state |= shExtra;
- #endif
- #endif
- return state;
- }
- #endif
-
- #ifndef HAVE_CRT_SIGNAL_HANDLERS
- #ifdef SIGINT
- static void int_handler (int sig)
- {
- (void) sig;
- if (crt_CheckBreak) /* PDCurses under DJGPP gets a SIGINT for Ctrl-C even in raw mode */
- crt_signal_handler (0x100 * ksInt);
- signal (SIGINT, &int_handler);
- }
- #endif
-
- #ifdef SIGTERM
- static void term_handler (int sig)
- {
- (void) sig;
- #ifdef XCURSES
- crt_ShutDown = TRUE;
- #endif
- crt_signal_handler (0x100 * ksTerm);
- signal (SIGTERM, &term_handler);
- }
- #endif
-
- #ifdef SIGHUP
- static void hup_handler (int sig)
- {
- (void) sig;
- #ifdef XCURSES
- crt_ShutDown = TRUE;
- #endif
- crt_signal_handler (0x100 * ksHUp);
- signal (SIGHUP, &hup_handler);
- }
- #endif
-
- #if defined (SIGPIPE) && defined (XCURSES)
- static void pipe_handler (int sig)
- {
- (void) sig;
- crt_ShutDown = TRUE;
- crt_signal_handler (0x100 * ksHUp);
- signal (SIGPIPE, SIG_IGN);
- if (crt_ShutDownJumpActive)
- longjmp (crt_ShutDownJump, 1);
- }
- #endif
-
- #if defined (SIGTSTP) && !defined (XCURSES)
- static void (*crt_old_tstp_handler) (int);
-
- static void tstp_handler (int sig)
- {
- (void) sig;
- signal (SIGTSTP, crt_old_tstp_handler);
- kill (getpid (), SIGTSTP);
- signal (SIGTSTP, &tstp_handler);
- crt_screen_size_changed = TRUE; /* might have changed while we were stopped */
- }
- #endif
-
- #ifdef SIGWINCH
- static void (*crt_old_winch_handler) (int);
-
- static void winch_handler (int sig)
- {
- crt_screen_size_changed = TRUE;
- crt_Signaled = TRUE;
- if (crt_old_winch_handler != SIG_ERR && crt_old_winch_handler != SIG_IGN && crt_old_winch_handler != SIG_DFL)
- (*crt_old_winch_handler) (sig);
- signal (SIGWINCH, &winch_handler);
- }
- #endif
-
- static void crt_init_signals ()
- {
- #ifdef SIGINT
- signal (SIGINT, &int_handler);
- #endif
- #ifdef SIGTERM
- signal (SIGTERM, &term_handler);
- #endif
- #ifdef SIGHUP
- signal (SIGHUP, &hup_handler);
- #endif
- #if defined (SIGPIPE) && defined (XCURSES)
- signal (SIGPIPE, &pipe_handler);
- #endif
- #if defined (SIGTSTP) && !defined (XCURSES)
- crt_old_tstp_handler = signal (SIGTSTP, &tstp_handler);
- #endif
- #ifdef SIGWINCH
- crt_old_winch_handler = signal (SIGWINCH, &winch_handler);
- #endif
- }
- #endif
-
- #if !defined (HAVE_CRT_SOUND) && !defined (NO_CRT_DUMMY_SOUND)
- void crt_sound (unsigned Hz)
- {
- }
-
- void crt_nosound ()
- {
- }
- #endif
-
- #if defined (USE_NCURSES) || defined (XCURSES)
-
- #include <sys/time.h>
-
- /* Time for delayed refreshes */
- #define REFRESH_SECONDS 0
- #define REFRESH_MICROSECONDS 100000
-
- static void alarm_handler (int sig)
- {
- (void) sig;
- crt_refresh ();
- }
-
- static void no_alarm_handler (int sig)
- {
- (void) sig;
- }
-
- /*
- This function must call crt_refresh(), either immediately, or
- delayed (e.g. using a timer signal).
- - Calling crt_refresh() immediately is useful if curses'
- wrefresh() does not take a long time, like PDCurses under DJGPP
- which uses direct hardware access. The CRT window will then
- always be up to date. However, if wrefresh() takes a long time,
- this will slow down the program substantially.
- - Calling crt_refresh() delayed (e.g. Unix with ncurses): By
- using a timer, the number of calls to wrefresh() can be reduced
- so the program will not be slowed down too much. On the other
- hand, the timer guarantees that the window will not lag behind
- more than a specified amount of time. crt_refresh() is
- re-entrant, so the timer signal handler can call it without
- worries. Also, crt_schedule_refresh() will not be called when
- there is a pending refresh (i.e. crt_schedule_refresh() was
- called, but crt_refresh() was not called since then), so it can
- set the timer without worrying about disturbing a previously
- scheduled refresh.
- */
- static void crt_schedule_refresh ()
- {
- static struct itimerval timerval = { { 0, 0 }, { REFRESH_SECONDS, REFRESH_MICROSECONDS } };
- signal (SIGALRM, &alarm_handler);
- setitimer (ITIMER_REAL, &timerval, 0);
- }
-
- /* Called before a Delay is started, a (blocking) read is done, a
- child process is executed, or the update level is changed, i.e.
- when a scheduled refresh should not be done any more because it
- or its timer event might disturb another operation. If
- crt_schedule_refresh() has set a timer, this function must clear
- it, otherwise it might interfere with the Delay or the read, so
- e.g. Delay might get too short or the read will not read in all
- characters. crt_refresh() will be called after this function, so
- the timer can safely be cleared without losing the refresh. */
- static void crt_stop_refresh ()
- {
- static struct itimerval no_timerval = { { 0, 0 }, { 0, 0 } };
- signal (SIGALRM, &no_alarm_handler);
- setitimer (ITIMER_REAL, &no_timerval, 0);
- }
-
- #else
-
- static inline void crt_schedule_refresh ()
- {
- crt_refresh ();
- }
-
- static void crt_stop_refresh ()
- {
- }
- #endif
-
- static void crt_setcbreak ()
- {
- if (crt_CheckBreak)
- {
- noraw ();
- cbreak ();
- }
- else
- raw ();
- }
-
- static void crt_nodelay (bool bf)
- {
- crt_setcbreak ();
- nodelay (crt_ActivePanel -> w, bf);
- nodelay (stdscr, bf);
- }
-
- static void crt_checkcheckbreak ()
- {
- if (crt_CheckBreak != crt_LastCheckBreak)
- {
- crt_LastCheckBreak = crt_CheckBreak;
- crt_setcbreak ();
- }
- }
-
- static TPanel CheckPanel (TPanel Panel)
- {
- TPanel PList = crt_PanelList;
- while (PList && PList != Panel) PList = PList -> Next;
- return PList;
- }
-
- TPanel crt_PanelAbove (TPanel Panel);
- TPanel crt_PanelAbove (TPanel Panel)
- {
- PANEL *p;
- if (Panel && !CheckPanel (Panel)) return NULL;
- p = Panel ? Panel -> panel : NULL;
- do
- p = panel_above (p);
- while (p && !panel_userptr (p));
- return p ? (TPanel) panel_userptr (p) : NULL;
- }
-
- TPanel crt_PanelBelow (TPanel Panel);
- TPanel crt_PanelBelow (TPanel Panel)
- {
- PANEL *p;
- if (Panel && !CheckPanel (Panel)) return NULL;
- p = Panel ? Panel -> panel : NULL;
- do
- p = panel_below (p);
- while (p && !panel_userptr (p));
- return p ? (TPanel) panel_userptr (p) : NULL;
- }
-
- static TCursorShape GetAbsCursorPos (int *PosX, int *PosY, chtype *CharUnderCursor)
- {
- int covered, x = 1, y = 1;
- TCursorShape shape;
- TPanel Panel, Panel2;
- for (Panel = crt_PanelBelow (NULL), shape = CursorIgnored;
- Panel && (shape = Panel -> CursorShape) == CursorIgnored;
- Panel = crt_PanelBelow (Panel));
- if (Panel)
- {
- getyx (Panel -> w, y, x);
- x += Panel -> WindXMin;
- y += Panel -> WindYMin;
- for (covered = 0, Panel2 = crt_PanelAbove (Panel); !covered && Panel2; Panel2 = crt_PanelAbove (Panel2))
- if (x >= Panel2 -> WindXMin && x <= Panel2 -> WindXMax &&
- y >= Panel2 -> WindYMin && y <= Panel2 -> WindYMax) covered = 1;
- if (covered) shape = CursorHidden;
- if (CharUnderCursor) *CharUnderCursor = winch (Panel -> w);
- }
- if (shape == CursorIgnored) shape = CursorHidden;
- *PosX = x - 1;
- *PosY = y - 1;
- return shape;
- }
-
- static void crt_update ()
- {
- int x, y;
- TCursorShape shape;
- if (crt_screen_size_changed || crt_ShutDown) return;
- #ifdef XCURSES
- crt_ShutDownJumpActive = TRUE;
- if (setjmp (crt_ShutDownJump))
- return;
- #endif
- shape = GetAbsCursorPos (&x, &y, NULL);
- update_panels ();
- if (shape != crt_last_shape)
- {
- crt_last_shape = shape;
- curs_set ((shape == CursorHidden) ? 0 :
- (shape == CursorNormal) ? 1 : 2);
- }
- if (shape == CursorHidden)
- {
- SETCURSOR (0, 0);
- wmove (stdscr, 0, 0);
- }
- else
- {
- SETCURSOR (x, y);
- wmove (stdscr, y, x);
- }
- doupdate ();
- #ifdef XCURSES
- crt_ShutDownJumpActive = FALSE;
- #endif
- }
-
- /* Must be re-entrant! */
- static void crt_refresh ()
- {
- if (crt_refresh_inhibit == 0)
- {
- crt_refresh_inhibit++;
- crt_pending_refresh = FALSE;
- crt_update ();
- (void) idlok (crt_ActivePanel -> w, FALSE);
- crt_refresh_inhibit--;
- }
- else
- crt_refresh_flag++;
- }
-
- static void crt_need_refresh ()
- {
- crt_checkcheckbreak ();
- if (crt_update_level >= UpdateAlways || crt_refresh_flag)
- {
- crt_refresh_flag = 0;
- crt_refresh ();
- }
- else if (crt_update_level >= UpdateRegularly && !crt_pending_refresh)
- {
- crt_pending_refresh = TRUE;
- crt_schedule_refresh ();
- }
- }
-
- void crt_SimulateBlockCursor (void);
- void crt_SimulateBlockCursor ()
- {
- if (!crt_SimulateBlockCursorActive)
- {
- int x, y;
- chtype CharUnderCursor;
- if (GetAbsCursorPos (&x, &y, &CharUnderCursor) >= CursorFat)
- {
- crt_SimulateBlockCursorActive = TRUE;
- if (!crt_SimulateBlockCursorPanel)
- {
- WINDOW *w = newwin (1, 1, y, x);
- if (!w) DO_RETURN_ADDRESS (crt_fatal (6));
- keypad (w, TRUE);
- leaveok (w, FALSE);
- crt_SimulateBlockCursorPanel = new_panel (w);
- set_panel_userptr (crt_SimulateBlockCursorPanel, NULL);
- }
- else
- move_panel (crt_SimulateBlockCursorPanel, y, x);
- mvwaddch (panel_window (crt_SimulateBlockCursorPanel), 0, 0,
- (crt_linux_console ? (chBlock | A_ALTCHARSET) : ACS_BLOCK)
- | (CharUnderCursor & A_ATTRIBUTES & ~A_ALTCHARSET));
- show_panel (crt_SimulateBlockCursorPanel);
- top_panel (crt_SimulateBlockCursorPanel);
- }
- }
- else
- {
- crt_SimulateBlockCursorActive = FALSE;
- if (crt_SimulateBlockCursorPanel) hide_panel (crt_SimulateBlockCursorPanel);
- }
- crt_need_refresh ();
- }
-
- void crt_SimulateBlockCursorOff (void);
- void crt_SimulateBlockCursorOff ()
- {
- if (crt_SimulateBlockCursorActive) crt_SimulateBlockCursor ();
- }
-
- void crt_PanelHide (TPanel Panel);
- void crt_PanelHide (TPanel Panel)
- {
- if (CheckPanel (Panel) && !Panel -> Hidden)
- {
- crt_refresh_inhibit++;
- hide_panel (Panel -> panel);
- Panel -> Hidden = TRUE;
- crt_refresh_inhibit--;
- crt_need_refresh ();
- }
- }
-
- void crt_PanelShow (TPanel Panel);
- void crt_PanelShow (TPanel Panel)
- {
- if (CheckPanel (Panel) && Panel -> Hidden)
- {
- crt_refresh_inhibit++;
- show_panel (Panel -> panel);
- Panel -> Hidden = FALSE;
- crt_refresh_inhibit--;
- crt_need_refresh ();
- }
- }
-
- Boolean crt_PanelHidden (TPanel Panel);
- Boolean crt_PanelHidden (TPanel Panel)
- {
- return CheckPanel (Panel) && Panel -> Hidden;
- }
-
- void crt_PanelTop (TPanel Panel);
- void crt_PanelTop (TPanel Panel)
- {
- if (!CheckPanel (Panel)) return;
- if (Panel -> Hidden) crt_PanelShow (Panel);
- crt_refresh_inhibit++;
- top_panel (Panel -> panel);
- crt_refresh_inhibit--;
- crt_need_refresh ();
- }
-
- void crt_PanelBottom (TPanel Panel);
- void crt_PanelBottom (TPanel Panel)
- {
- if (!CheckPanel (Panel)) return;
- if (Panel -> Hidden) crt_PanelShow (Panel);
- crt_refresh_inhibit++;
- bottom_panel (Panel -> panel);
- crt_refresh_inhibit--;
- crt_need_refresh ();
- }
-
- void crt_PanelMoveAbove (TPanel Panel, TPanel Above);
- void crt_PanelMoveAbove (TPanel Panel, TPanel Above)
- {
- if (!CheckPanel (Panel)) return;
- if (!CheckPanel (Above))
- crt_PanelBottom (Panel);
- else if (Above -> Hidden)
- crt_PanelHide (Panel);
- else if (Above != Panel)
- {
- PANEL *p, *p2;
- if (Panel -> Hidden) crt_PanelShow (Panel);
- crt_refresh_inhibit++;
- top_panel (Panel -> panel);
- p = panel_above (Above -> panel);
- while (p && p != Panel -> panel)
- {
- p2 = panel_above (p);
- top_panel (p);
- p = p2;
- }
- crt_refresh_inhibit--;
- crt_need_refresh ();
- }
- }
-
- void crt_PanelMoveBelow (TPanel Panel, TPanel Below);
- void crt_PanelMoveBelow (TPanel Panel, TPanel Below)
- {
- if (!CheckPanel (Panel)) return;
- if (!CheckPanel (Below))
- crt_PanelTop (Panel);
- else if (Below -> Hidden)
- crt_PanelHide (Panel);
- else if (Below != Panel)
- {
- PANEL *p, *p2;
- if (Panel -> Hidden) crt_PanelShow (Panel);
- crt_refresh_inhibit++;
- bottom_panel (Panel -> panel);
- p = panel_below (Below -> panel);
- while (p && p != Panel -> panel)
- {
- p2 = panel_below (p);
- bottom_panel (p);
- p = p2;
- }
- crt_refresh_inhibit--;
- crt_need_refresh ();
- }
- }
-
- void crt_PanelBindToBackground (TPanel Panel, Boolean Bind);
- void crt_PanelBindToBackground (TPanel Panel, Boolean Bind)
- {
- if (CheckPanel (Panel)) Panel -> BoundToBackground = Bind;
- }
-
- Boolean crt_PanelIsBoundToBackground (TPanel Panel);
- Boolean crt_PanelIsBoundToBackground (TPanel Panel)
- {
- return CheckPanel (Panel) && Panel -> BoundToBackground;
- }
-
- static WINDOW *crt_newwin (int x1, int y1, int x2, int y2, Boolean BoundToBackground)
- {
- int xsize = x2 - x1 + 1, ysize = y2 - y1 + 1;
- WINDOW *w = newwin (ysize, xsize, y1 - 1, x1 - 1);
- if (!w) DO_RETURN_ADDRESS (crt_fatal (6));
- if (BoundToBackground)
- {
- chtype Buffer [xsize + 1];
- int yc;
- for (yc = 0; yc < ysize; yc++)
- {
- mvwinchnstr (stdscr, yc + y1 - 1, x1 - 1, Buffer, xsize);
- mvwaddchnstr (w, yc, 0, Buffer, xsize);
- }
- }
- keypad (w, TRUE);
- leaveok (w, FALSE);
- crt_last_shape = - 1;
- return w;
- }
-
- /* Save contents of the panel to stdscr to imitate BP behaviour */
- static void savetostdscr (TPanel Panel)
- {
- if (Panel -> BoundToBackground)
- {
- PANEL *panel;
- int yc,
- XMin = Panel -> WindXMin - 1,
- YMin = Panel -> WindYMin - 1,
- XSize = Panel -> WindXMax - XMin,
- YSize = Panel -> WindYMax - YMin;
- chtype Buffer [XSize + 1];
- for (yc = 0; yc < YSize; yc++)
- {
- mvwinchnstr (Panel -> w, yc, 0, Buffer, XSize);
- mvwaddchnstr (stdscr, yc + YMin, XMin, Buffer, XSize);
- }
- wnoutrefresh (stdscr);
- for (panel = panel_above (NULL); panel; panel = panel_above (panel))
- touchwin (panel_window (panel));
- }
- }
-
- static void crt_dosetscroll ()
- {
- scrollok (crt_ActivePanel -> w, crt_ActivePanel -> ScrollState);
- }
-
- static void update_crt_cursor_pos ()
- {
- getyx (crt_ActivePanel -> w, crt_cursor_pos.y, crt_cursor_pos.x);
- }
-
- static inline int combine_bytes (int lo, int hi)
- {
- return ((lo > 254) ? 254 : lo) +
- (((hi > 254) ? 254 : hi) << 8);
- }
-
- static void SetWindow (TPanel p, int x1, int y1, int x2, int y2)
- {
- p -> WindXMin = x1;
- p -> WindYMin = y1;
- p -> WindXMax = x2;
- p -> WindYMax = y2;
- p -> LastWindMin = combine_bytes (x1 - 1, y1 - 1);
- p -> LastWindMax = combine_bytes (x2 - 1, y2 - 1);
- }
-
- static void crt_UpdateDataToActivePanel ()
- {
- if (crt_ActivePanel)
- crt_ActivePanel -> TextAttr = crt_TextAttr;
- }
-
- static void crt_UpdateDataFromActivePanel ()
- {
- if (crt_ActivePanel)
- {
- crt_TextAttr = crt_ActivePanel -> TextAttr;
- crt_WindMin = combine_bytes (crt_ActivePanel -> WindXMin - 1, crt_ActivePanel -> WindYMin - 1);
- crt_WindMax = combine_bytes (crt_ActivePanel -> WindXMax - 1, crt_ActivePanel -> WindYMax - 1);
- update_crt_cursor_pos ();
- }
- }
-
- static void change_win (int x1, int y1, int x2, int y2)
- {
- int x, y;
- WINDOW *oldwin = crt_ActivePanel -> w;
- crt_refresh_inhibit++;
- if (x2 < 1) x2 = 1; if (x2 > crt_ScreenSize.x) x2 = crt_ScreenSize.x;
- if (y2 < 1) y2 = 1; if (y2 > crt_ScreenSize.y) y2 = crt_ScreenSize.y;
- if (x1 < 1) x1 = 1; if (x1 > x2) x1 = x2;
- if (y1 < 1) y1 = 1; if (y1 > y2) y1 = y2;
- getyx (crt_ActivePanel -> w, y, x);
- x += crt_ActivePanel -> WindXMin;
- y += crt_ActivePanel -> WindYMin;
- savetostdscr (crt_ActivePanel);
- crt_ActivePanel -> w = crt_newwin (x1, y1, x2, y2, crt_ActivePanel -> BoundToBackground);
- replace_panel (crt_ActivePanel -> panel, crt_ActivePanel -> w);
- delwin (oldwin);
- crt_last_shape = - 1;
- crt_dosetscroll ();
- if (x < x1) x = x1;
- if (x > x2) x = x2;
- if (y < y1) y = y1;
- if (y > y2) y = y2;
- wmove (crt_ActivePanel -> w, y - y1, x - x1);
- SetWindow (crt_ActivePanel, x1, y1, x2, y2);
- crt_WindMin = crt_ActivePanel -> LastWindMin;
- crt_WindMax = crt_ActivePanel -> LastWindMax;
- crt_refresh_inhibit--;
- update_crt_cursor_pos ();
- crt_need_refresh ();
- }
-
- static void crt_PanelActivate_Internal (TPanel Panel)
- {
- if (!CheckPanel (Panel)) DO_RETURN_ADDRESS (crt_fatal (5));
- if (Panel == crt_ActivePanel) return;
- crt_UpdateDataToActivePanel ();
- crt_ActivePanel = Panel;
- crt_UpdateDataFromActivePanel ();
- }
-
- static void crt_PanelNew_Internal (int x1, int y1, int x2, int y2, Boolean BindToBackground)
- {
- TPanel NewPanel = malloc (sizeof (TPanelData));
- crt_refresh_inhibit++;
- NewPanel -> Next = crt_PanelList;
- crt_PanelList = NewPanel;
- if (x2 < 1) x2 = 1; if (x2 > crt_ScreenSize.x) x2 = crt_ScreenSize.x;
- if (y2 < 1) y2 = 1; if (y2 > crt_ScreenSize.y) y2 = crt_ScreenSize.y;
- if (x1 < 1) x1 = 1; if (x1 > x2) x1 = x2;
- if (y1 < 1) y1 = 1; if (y1 > y2) y1 = y2;
- NewPanel -> BoundToBackground = BindToBackground;
- NewPanel -> Hidden = FALSE;
- NewPanel -> ScrollState = crt_ActivePanel ? crt_ActivePanel -> ScrollState : TRUE;
- NewPanel -> PCCharSet = crt_ActivePanel ? crt_ActivePanel -> PCCharSet : crt_PCCharSet;
- NewPanel -> UseControlChars = crt_ActivePanel ? crt_ActivePanel -> UseControlChars : TRUE;
- NewPanel -> CursorShape = crt_ActivePanel ? crt_ActivePanel -> CursorShape : CursorNormal;
- NewPanel -> TextAttr = crt_TextAttr;
- NewPanel -> w = crt_newwin (x1, y1, x2, y2, NewPanel -> BoundToBackground);
- NewPanel -> panel = new_panel (NewPanel -> w);
- set_panel_userptr (NewPanel -> panel, (void *) NewPanel);
- SetWindow (NewPanel, x1, y1, x2, y2);
- crt_PanelActivate_Internal (NewPanel);
- wmove (NewPanel -> w, 0, 0);
- update_crt_cursor_pos ();
- crt_dosetscroll ();
- crt_refresh_inhibit--;
- }
-
- static void crt_GetLastMode ()
- {
- if (crt_HasColors)
- {
- crt_LastMode = 0;
- if (crt_ColorFlag) crt_LastMode += 1;
- if (crt_ScreenSize.x >= 80) crt_LastMode += 2;
- }
- else
- crt_LastMode = 7;
- if (crt_ScreenSize.y >= 43) crt_LastMode += 0x100;
- crt_IsMonochrome = !crt_HasColors || !crt_ColorFlag;
- }
-
- static int crt_attr2cursattr (TTextAttr attr)
- {
- #ifdef XCURSES
- /* PDCurses under X has serious problems writing black on black. :-(
- So we write some other color on black and output spaces (see chtransform()) */
- if ((attr & ~0x88) == 0) attr = 7;
- #endif
- return (crt_ColorFlag ? crt_attrs : crt_monoattrs) [attr & 7] [(attr >> 4) & 7] |
- (((attr & 8) && (crt_ColorFlag || (attr & 0x77))) ? A_BOLD : 0) |
- ((attr & 0x80) ? A_BLINK : 0);
- }
-
- static void crt_rawout (Boolean flag)
- {
- #ifdef HAVE_RAW_OUTPUT
- raw_output (flag);
- #else
- (void) flag;
- #endif
- }
-
- static void crt_set_typeahead ()
- {
- typeahead ((crt_update_level == UpdateWaitInput) ? crt_get_input_fd () : - 1);
- }
-
- void crt_save_previous_screen (void);
- void crt_save_previous_screen ()
- {
- if (crt_save_previous_screen_flag < 0)
- crt_save_previous_screen_flag = crt_save_restore_screen (FALSE);
- }
-
- Boolean crt_save_previous_screen_works (void);
- Boolean crt_save_previous_screen_works ()
- {
- if (crt_save_previous_screen_flag == - 1)
- crt_save_previous_screen_flag = crt_save_restore_screen (FALSE);
- return crt_save_previous_screen_flag > 0;
- }
-
- void crt_init (void);
- void crt_init ()
- {
- int fg, bg, c, cursattr;
- #ifdef USE_NCURSES
- FILE *crt_file_out = NULL, *crt_file_in = NULL;
- #endif
- if (crt_inited) return;
- SAVE_RETURN_ADDRESS;
- #ifdef XCURSES
- XCursesProgramName = crt_get_program_name ();
- #endif
- crt_screen_size_changed = FALSE;
- #ifndef USE_NCURSES
- crt_output_fd = fileno (stdout);
- crt_input_fd = fileno (stdin);
- #else
- if (crt_output_fd < 0)
- crt_output_fd = fileno (stdout);
- else if (!(crt_file_out = fdopen (crt_output_fd, "w")))
- crt_fatal (1);
- if (crt_input_fd < 0)
- crt_input_fd = fileno (stdin);
- else if (!(crt_file_in = fdopen (crt_input_fd, "r")))
- {
- if (crt_file_out) fclose (crt_file_out);
- crt_fatal (1);
- }
- if (crt_term || crt_file_in || crt_file_out)
- {
- char *value_str, *value_end;
- int value;
- if (!newterm (crt_term, crt_file_out ? crt_file_out : stdout, crt_file_in ? crt_file_in : stdin))
- crt_fatal (2);
- if ((value_str = getenv ("ESCDELAY")) &&
- (value = strtol (value_str, &value_end, 10)) >= 0 && (!value_end || !*value_end))
- ESCDELAY = value;
- def_prog_mode ();
- }
- else
- #endif
- if (!initscr ()) crt_fatal (1);
- crt_dummy_pad = newpad (1, 1);
- crt_inited = 1;
- #ifdef XCURSES
- sleep (1); /* @@There is a problem with XCurses not always starting up
- correctly (race condition?). Until it is solved, this
- sleep() is an ugly and unreliable way to avoid it
- sometimes... */
- #endif
- #ifdef USE_PDCURSES
- PDC_save_key_modifiers (TRUE);
- #else
- crt_linux_console = strncmp (termname (), "linux", 5) == 0;
- /* Work-around for the problem that ncurses ignores the A_BOLD attribute
- when clearing which may cause a wrong cursor color. */
- if (crt_linux_console)
- back_color_erase = 0;
- #endif
- #if !defined (USE_PDCURSES) || defined (XCURSES)
- chars_0_31 [ 4] = ACS_DIAMOND;
- chars_0_31 [16] = ACS_RARROW;
- chars_0_31 [17] = ACS_LARROW;
- chars_0_31 [18] = ACS_VLINE;
- chars_0_31 [22] = ACS_S9;
- chars_0_31 [23] = ACS_DARROW;
- chars_0_31 [24] = ACS_UARROW;
- chars_0_31 [25] = ACS_DARROW;
- chars_0_31 [26] = ACS_RARROW;
- chars_0_31 [27] = ACS_LARROW;
- chars_0_31 [28] = ACS_LLCORNER;
- chars_0_31 [29] = ACS_HLINE;
- chars_0_31 [30] = ACS_UARROW;
- chars_0_31 [31] = ACS_DARROW;
- chars_128_255 [ 28] = ACS_STERLING;
- chars_128_255 [ 38] = ACS_DEGREE;
- chars_128_255 [ 39] = ACS_DEGREE;
- chars_128_255 [ 41] = ACS_ULCORNER;
- chars_128_255 [ 42] = ACS_URCORNER;
- chars_128_255 [ 46] = ACS_LARROW;
- chars_128_255 [ 47] = ACS_RARROW;
- chars_128_255 [ 48] = ACS_CKBOARD;
- chars_128_255 [ 49] = ACS_CKBOARD;
- chars_128_255 [ 50] = ACS_CKBOARD;
- chars_128_255 [ 51] = ACS_VLINE;
- chars_128_255 [ 52] = ACS_RTEE;
- chars_128_255 [ 53] = ACS_RTEE;
- chars_128_255 [ 54] = ACS_RTEE;
- chars_128_255 [ 55] = ACS_URCORNER;
- chars_128_255 [ 56] = ACS_URCORNER;
- chars_128_255 [ 57] = ACS_RTEE;
- chars_128_255 [ 58] = ACS_VLINE;
- chars_128_255 [ 59] = ACS_URCORNER;
- chars_128_255 [ 60] = ACS_LRCORNER;
- chars_128_255 [ 61] = ACS_LRCORNER;
- chars_128_255 [ 62] = ACS_LRCORNER;
- chars_128_255 [ 63] = ACS_URCORNER;
- chars_128_255 [ 64] = ACS_LLCORNER;
- chars_128_255 [ 65] = ACS_BTEE;
- chars_128_255 [ 66] = ACS_TTEE;
- chars_128_255 [ 67] = ACS_LTEE;
- chars_128_255 [ 68] = ACS_HLINE;
- chars_128_255 [ 69] = ACS_PLUS;
- chars_128_255 [ 70] = ACS_LTEE;
- chars_128_255 [ 71] = ACS_LTEE;
- chars_128_255 [ 72] = ACS_LLCORNER;
- chars_128_255 [ 73] = ACS_ULCORNER;
- chars_128_255 [ 74] = ACS_BTEE;
- chars_128_255 [ 75] = ACS_TTEE;
- chars_128_255 [ 76] = ACS_LTEE;
- chars_128_255 [ 77] = ACS_HLINE;
- chars_128_255 [ 78] = ACS_PLUS;
- chars_128_255 [ 79] = ACS_BTEE;
- chars_128_255 [ 80] = ACS_BTEE;
- chars_128_255 [ 81] = ACS_TTEE;
- chars_128_255 [ 82] = ACS_TTEE;
- chars_128_255 [ 83] = ACS_LLCORNER;
- chars_128_255 [ 84] = ACS_LLCORNER;
- chars_128_255 [ 85] = ACS_ULCORNER;
- chars_128_255 [ 86] = ACS_ULCORNER;
- chars_128_255 [ 87] = ACS_PLUS;
- chars_128_255 [ 88] = ACS_PLUS;
- chars_128_255 [ 89] = ACS_LRCORNER;
- chars_128_255 [ 90] = ACS_ULCORNER;
- chars_128_255 [ 91] = ACS_BLOCK;
- chars_128_255 [ 92] = ACS_BLOCK;
- chars_128_255 [ 93] = ACS_BLOCK;
- chars_128_255 [ 94] = ACS_BLOCK;
- chars_128_255 [ 95] = ACS_BLOCK;
- chars_128_255 [ 99] = ACS_PI;
- chars_128_255 [113] = ACS_PLMINUS;
- chars_128_255 [114] = ACS_GEQUAL;
- chars_128_255 [115] = ACS_LEQUAL;
- chars_128_255 [120] = ACS_DEGREE;
- chars_128_255 [126] = ACS_BULLET;
- #endif
- cbreak ();
- noecho ();
- scrollok (stdscr, TRUE);
- crt_rawout (TRUE);
- crt_ColorFlag = crt_HasColors = has_colors ();
- if (crt_HasColors)
- {
- start_color ();
- c = 0;
- for (bg = 0; bg < 8; bg++)
- for (fg = 0; fg < 8; fg++)
- if (INVIS_WORKS && bg == fg && bg > 0)
- crt_attrs [fg] [bg] = crt_attrs [0] [bg] | A_INVIS;
- else if (REVERSE_WORKS && fg < bg)
- crt_attrs [fg] [bg] = crt_attrs [bg] [fg] | A_REVERSE;
- else
- {
- if (init_pair (++c, crt_colors [fg], crt_colors [bg]) == ERR)
- {
- fprintf (stderr, "could not create color pair (%i,%i)", fg, bg);
- crt_inited = 0;
- #ifdef XCURSES
- XCursesExit ();
- #endif
- exit (1);
- }
- crt_attrs [fg] [bg] = COLOR_PAIR (c);
- }
- for (bg = 0; bg < 8; bg++)
- for (fg = 0; fg < 8; fg++)
- crt_monoattrs [fg] [bg] = crt_attrs [7] [0];
- crt_monoattrs [0] [0] = crt_attrs [0] [0];
- crt_monoattrs [1] [0] = crt_attrs [1] [0];
- crt_monoattrs [0] [7] = crt_attrs [0] [7];
- }
- else
- {
- for (bg = 0; bg < 8; bg++)
- for (fg = 0; fg < 8; fg++)
- crt_monoattrs [fg] [bg] = A_NORMAL;
- crt_monoattrs [0] [0] = A_INVIS;
- crt_monoattrs [1] [0] = A_UNDERLINE;
- crt_monoattrs [0] [7] = A_REVERSE;
- }
- cursattr = crt_attr2cursattr (crt_NormAttr);
- attrset (cursattr);
- bkgdset (cursattr);
- erase ();
- crt_init_signals ();
- keypad (stdscr, TRUE);
- getmaxyx (stdscr, crt_ScreenSize.y, crt_ScreenSize.x);
- wrefresh (stdscr); /* prevents flickering at the beginning of XCurses programs */
- crt_GetLastMode ();
- crt_PanelNew_Internal (1, 1, crt_ScreenSize.x, crt_ScreenSize.y, TRUE);
- typeahead (- 1);
- crt_set_typeahead ();
- crt_registerrestoreterminal ();
- RESTORE_RETURN_ADDRESS;
- }
-
- static void crt_bp_autoinit ()
- {
- static Boolean initializing = FALSE;
- if (initializing) /* in case crt_auto_init_proc causes CRT to auto init again... */
- initializing = FALSE;
- else
- {
- initializing = TRUE;
- if (crt_auto_init_proc) (*crt_auto_init_proc) ();
- if (!initializing) return;
- initializing = FALSE;
- }
- crt_PCCharSet = TRUE;
- if (!crt_UpdateLevelChanged) crt_update_level = UpdateRegularly;
- crt_init ();
- }
-
- static void adjust_size (int *x1, int *y1, int *x2, int *y2, TPoint LastScreenSize)
- {
- if (*x2 > crt_ScreenSize.x)
- {
- *x1 -= *x2 - crt_ScreenSize.x;
- if (*x1 < 1) *x1 = 1;
- *x2 = crt_ScreenSize.x;
- }
- else if (*x1 == 1 && *x2 == LastScreenSize.x)
- *x2 = crt_ScreenSize.x;
- if (*y2 > crt_ScreenSize.y)
- {
- *y1 -= *y2 - crt_ScreenSize.y;
- if (*y1 < 1) *y1 = 1;
- *y2 = crt_ScreenSize.y;
- }
- else if (*y1 == 1 && *y2 == LastScreenSize.y)
- *y2 = crt_ScreenSize.y;
- }
-
- static void adjust_panel (PANEL *panel, WINDOW **w, int x1, int y1, int x2, int y2)
- {
- int x, y, xsize = x2 - x1 + 1, ysize = y2 - y1 + 1;
- WINDOW *new;
- /* It's not very clear what has to be updated in the windows and
- panels, and in which order (in the different curses libraries).
- So, we rather do too much than too little. First resize, then
- move, otherwise the move could fail, because the window might
- not fit on the screen. */
- getyx ((*w), y, x);
- new = resize_window ((*w), ysize, xsize);
- if (new) *w = new;
- panel->win = *w;
- replace_panel (panel, (*w));
- move_panel (panel, y1 - 1, x1 - 1);
- if (x >= xsize) x = xsize - 1;
- if (y >= ysize) y = ysize - 1;
- wmove ((*w), y, x);
- keypad ((*w), TRUE);
- leaveok ((*w), FALSE);
- }
-
- void crt_check_winchanged ()
- {
- SAVE_RETURN_ADDRESS;
- if (!crt_inited) crt_bp_autoinit ();
- #ifdef USE_PDCURSES
- /* In XCurses, this wouldn't be necessary (but doesn't hurt)
- because the program will get a SIGWINCH, but e.g. under mingw,
- it doesn't get a SIGWINCH, so we need this additional check. */
- if (is_termresized ()) crt_screen_size_changed = TRUE;
- #endif
- if (crt_screen_size_changed)
- {
- PANEL *panel;
- TPanel p;
- TPoint LastScreenSize;
- crt_refresh_inhibit++;
- #ifdef USE_PDCURSES
- /* XCurses: resize the terminal after the user resized the window */
- if (is_termresized ()) resize_term (0, 0);
- /* work around a bug in the PDCurses panel library */
- {
- extern PANEL __stdscr_pseudo_panel;
- __stdscr_pseudo_panel.win = stdscr;
- __stdscr_pseudo_panel.wendy = LINES;
- __stdscr_pseudo_panel.wendx = COLS;
- }
- #endif
- napms (100); /* wait for a new unimap to be loaded if necessary */
- /* The following code is a bit tricky...
- doupdate() will update the screen size in ncurses, but the
- size or position of any window may have become invalid, so
- they must not be updated now! */
- untouchwin (stdscr);
- for (panel = panel_above (NULL); panel; panel = panel_above (panel))
- untouchwin (panel_window (panel));
- if (!crt_ShutDown)
- doupdate ();
- LastScreenSize = crt_ScreenSize;
- getmaxyx (stdscr, crt_ScreenSize.y, crt_ScreenSize.x);
- /* Resize all CRT panels */
- for (p = crt_PanelList; p; p = p -> Next)
- {
- Boolean SetWinMinMax = p == crt_ActivePanel
- && crt_WindMin == p -> LastWindMin
- && crt_WindMax == p -> LastWindMax;
- int x1, y1, x2, y2;
- x1 = p -> WindXMin;
- y1 = p -> WindYMin;
- x2 = p -> WindXMax;
- y2 = p -> WindYMax;
- adjust_size (&x1, &y1, &x2, &y2, LastScreenSize);
- if (x1 != p -> WindXMin || y1 != p -> WindYMin ||
- x2 != p -> WindXMax || y2 != p -> WindYMax)
- {
- p -> WindXMin = x1;
- p -> WindYMin = y1;
- p -> WindXMax = x2;
- p -> WindYMax = y2;
- SetWindow (p, x1, y1, x2, y2);
- if (SetWinMinMax)
- {
- crt_WindMin = p -> LastWindMin;
- crt_WindMax = p -> LastWindMax;
- }
- adjust_panel (p -> panel, &p -> w, x1, y1, x2, y2);
- if (p -> Hidden) hide_panel (p -> panel);
- }
- }
- /* Handle panels that don't belong to CRT windows (e.g., the one
- for the simulated block cursor) */
- for (panel = panel_above (NULL); panel; panel = panel_above (panel))
- if (!panel_userptr (panel))
- {
- WINDOW *w = panel_window (panel);
- int x1, y1, x2, y2, xsize, ysize, oldx1, oldy1, oldx2, oldy2;
- getbegyx (w, y1, x1);
- x1++;
- y1++;
- getmaxyx (w, ysize, xsize);
- oldx1 = x1;
- oldy1 = y1;
- oldx2 = x2 = x1 + xsize - 1;
- oldy2 = y2 = y1 + ysize - 1;
- adjust_size (&x1, &y1, &x2, &y2, LastScreenSize);
- if (x1 != oldx1 || y1 != oldy1 || x2 != oldx2 || y2 != oldy2)
- adjust_panel (panel, &w, x1, y1, x2, y2);
- }
- update_crt_cursor_pos ();
- /* Now we can refresh everything */
- touchwin (stdscr);
- for (panel = panel_above (NULL); panel; panel = panel_above (panel))
- touchwin (panel_window (panel));
- /* Overcome ncurses' buffering of the cursor shape, because sometimes
- when the screen size is changed (e.g. by SVGATextMode), also the
- cursor shape is reset. */
- curs_set (1);
- curs_set (0);
- crt_last_shape = CursorHidden;
- crt_dosetscroll ();
- crt_update ();
- crt_screen_size_changed = FALSE;
- crt_GetLastMode ();
- crt_refresh_inhibit--;
- if (crt_key_buf == 0) crt_key_buf = KEY_RESIZE;
- }
- if (crt_WindMin != crt_ActivePanel -> LastWindMin || crt_WindMax != crt_ActivePanel -> LastWindMax)
- change_win ((crt_WindMin & 0xff) + 1, (crt_WindMin >> 8) + 1,
- (crt_WindMax & 0xff) + 1, (crt_WindMax >> 8) + 1);
- RESTORE_RETURN_ADDRESS;
- }
-
- void crt_gotoxy (int x, int y);
- void crt_gotoxy (int x, int y)
- {
- DO_CRT_CHECK_WINCHANGED;
- wmove (crt_ActivePanel -> w, y - 1, x - 1);
- crt_cursor_pos.x = x - 1;
- crt_cursor_pos.y = y - 1;
- crt_need_refresh ();
- }
-
- int crt_wherex (void);
- int crt_wherex ()
- {
- int x, y;
- DO_CRT_CHECK_WINCHANGED;
- getyx (crt_ActivePanel -> w, y, x);
- return x + 1;
- }
-
- int crt_wherey (void);
- int crt_wherey ()
- {
- int x, y;
- DO_CRT_CHECK_WINCHANGED;
- getyx (crt_ActivePanel -> w, y, x);
- return y + 1;
- }
-
- void crt_window (int x1, int y1, int x2, int y2);
- void crt_window (int x1, int y1, int x2, int y2)
- {
- DO_CRT_CHECK_WINCHANGED;
- if (x1 >= 1 && x1 <= x2 && x2 <= crt_ScreenSize.x &&
- y1 >= 1 && y1 <= y2 && y2 <= crt_ScreenSize.y)
- {
- change_win (x1, y1, x2, y2);
- crt_gotoxy (1, 1);
- }
- }
-
- void crt_getwindow (int *x1, int *y1, int *x2, int *y2);
- void crt_getwindow (int *x1, int *y1, int *x2, int *y2)
- {
- DO_CRT_CHECK_WINCHANGED;
- if (x1) *x1 = crt_ActivePanel -> WindXMin;
- if (y1) *y1 = crt_ActivePanel -> WindYMin;
- if (x2) *x2 = crt_ActivePanel -> WindXMax;
- if (y2) *y2 = crt_ActivePanel -> WindYMax;
- }
-
- void crt_setscroll (Boolean state);
- void crt_setscroll (Boolean state)
- {
- DO_CRT_CHECK_WINCHANGED;
- crt_ActivePanel -> ScrollState = state;
- crt_dosetscroll ();
- }
-
- Boolean crt_getscroll (void);
- Boolean crt_getscroll ()
- {
- DO_CRT_CHECK_WINCHANGED;
- return crt_ActivePanel -> ScrollState;
- }
-
- void crt_setcursorshape (TCursorShape shape);
- void crt_setcursorshape (TCursorShape shape)
- {
- DO_CRT_CHECK_WINCHANGED;
- crt_ActivePanel -> CursorShape = shape;
- crt_need_refresh ();
- }
-
- TCursorShape crt_getcursorshape (void);
- TCursorShape crt_getcursorshape ()
- {
- DO_CRT_CHECK_WINCHANGED;
- return crt_ActivePanel -> CursorShape;
- }
-
- TPanel crt_GetActivePanel (void);
- TPanel crt_GetActivePanel ()
- {
- DO_CRT_CHECK_WINCHANGED;
- return crt_ActivePanel;
- }
-
- void crt_PanelActivate (TPanel Panel);
- void crt_PanelActivate (TPanel Panel)
- {
- if (Panel == crt_ActivePanel) return;
- DO_CRT_CHECK_WINCHANGED;
- DO_RETURN_ADDRESS (crt_PanelActivate_Internal (Panel));
- }
-
- void crt_PanelNew (int x1, int y1, int x2, int y2, Boolean BindToBackground);
- void crt_PanelNew (int x1, int y1, int x2, int y2, Boolean BindToBackground)
- {
- DO_CRT_CHECK_WINCHANGED;
- DO_RETURN_ADDRESS (crt_PanelNew_Internal (x1, y1, x2, y2, BindToBackground));
- crt_need_refresh ();
- }
-
- void crt_PanelDelete (TPanel Panel);
- void crt_PanelDelete (TPanel Panel)
- {
- TPanel *PList = &crt_PanelList;
- while (*PList && *PList != Panel) PList = &((*PList) -> Next);
- if (!*PList) DO_RETURN_ADDRESS (crt_fatal (3));
- DO_CRT_CHECK_WINCHANGED;
- crt_refresh_inhibit++;
- *PList = Panel -> Next;
- if (!crt_PanelList) DO_RETURN_ADDRESS (crt_fatal (4));
- savetostdscr (Panel);
- del_panel (Panel -> panel);
- delwin (Panel -> w);
- free (Panel);
- if (Panel == crt_ActivePanel)
- {
- crt_ActivePanel = NULL;
- crt_PanelActivate_Internal (crt_PanelList);
- }
- crt_last_shape = - 1;
- crt_refresh_inhibit--;
- crt_need_refresh ();
- }
-
- static TTextAttr cursattr2attr (int cursattr)
- {
- int attr = 0;
- cursattr &= (A_ATTRIBUTES & ~A_ALTCHARSET);
- if (crt_attr2cursattr (crt_NormAttr) == cursattr) return crt_NormAttr;
- while (attr < 0x100 && crt_attr2cursattr (attr) != cursattr) attr++;
- return (attr == 0x100) ? crt_NormAttr : attr;
- }
-
- static void crt_setattr ()
- {
- int cursattr;
- DO_CRT_CHECK_WINCHANGED;
- cursattr = crt_attr2cursattr (crt_TextAttr);
- wattrset (crt_ActivePanel -> w, cursattr);
- wbkgdset (crt_ActivePanel -> w, cursattr | ' ');
- }
-
- void crt_update_immediately (void);
- void crt_update_immediately ()
- {
- DO_CRT_CHECK_WINCHANGED;
- if (crt_update_level == UpdateRegularly) crt_stop_refresh ();
- typeahead (- 1);
- crt_refresh ();
- crt_set_typeahead ();
- }
-
- void crt_redraw (void);
- void crt_redraw ()
- {
- PANEL *panel;
- DO_CRT_CHECK_WINCHANGED;
- touchwin (stdscr);
- for (panel = panel_above (NULL); panel; panel = panel_above (panel))
- touchwin (panel_window (panel));
- clearok (curscr, TRUE);
- crt_last_shape = - 1;
- crt_update ();
- }
-
- void crt_setupdatelevel (TCRTUpdate level);
- void crt_setupdatelevel (TCRTUpdate level)
- {
- if (crt_inited)
- {
- DO_CRT_CHECK_WINCHANGED;
- if (crt_update_level == UpdateRegularly) crt_update_immediately ();
- }
- crt_update_level = level;
- crt_UpdateLevelChanged = TRUE;
- if (crt_inited) crt_set_typeahead ();
- }
-
- void crt_restore_terminal_no_crt (void);
- void crt_restore_terminal_no_crt ()
- {
- if (!crt_inited || crt_terminal_no_crt || crt_ShutDown) return;
- DO_CRT_CHECK_WINCHANGED; /* We DO need this here, otherwise the tputs in
- crt_clear_terminal() can cause a segfault. */
- if (crt_ActivePanel) DO_RETURN_ADDRESS (crt_update_immediately ());
- crt_terminal_no_crt = TRUE;
- #ifdef USE_PDCURSES
- savetty ();
- #endif
- if (crt_clearflag)
- {
- #ifdef USE_NCURSES
- if (isprivate (enter_ca_mode))
- {
- crt_save_enter_ca_mode = enter_ca_mode;
- enter_ca_mode = NULL;
- }
- if (isprivate (exit_ca_mode))
- {
- crt_save_exit_ca_mode = exit_ca_mode;
- exit_ca_mode = NULL;
- }
- #endif
- }
- endwin ();
- #if defined (SIGTSTP) && !defined (XCURSES)
- signal (SIGTSTP, SIG_DFL);
- #endif
- if (crt_clearflag
- || (crt_save_previous_screen_flag > 0 && !(crt_screen_restored = crt_save_restore_screen (TRUE) > 0))
- || crt_save_previous_screen_flag == 0)
- crt_clear_terminal ();
- }
-
- void crt_restore_terminal_crt (void);
- void crt_restore_terminal_crt ()
- {
- if (crt_ShutDown) return;
- if (!crt_inited || !crt_terminal_no_crt) return;
- DO_CRT_CHECK_WINCHANGED;
- if (crt_screen_restored)
- {
- crt_screen_restored = FALSE;
- crt_save_restore_screen (FALSE);
- }
- #ifdef USE_PDCURSES
- resetty ();
- SETCURSOR (0, 0); doupdate (); /* @@ resetty() seems to get the cursor position wrong */
- #endif
- #if defined (SIGTSTP) && !defined (XCURSES)
- signal (SIGTSTP, &tstp_handler);
- #endif
- crt_rawout (TRUE);
- clearok (curscr, TRUE);
- crt_last_shape = - 1;
- crt_update ();
- #ifdef USE_NCURSES
- if (crt_save_enter_ca_mode) enter_ca_mode = crt_save_enter_ca_mode;
- if (crt_save_exit_ca_mode) exit_ca_mode = crt_save_exit_ca_mode;
- crt_save_enter_ca_mode = crt_save_exit_ca_mode = NULL;
- #endif
- #ifdef USE_PDCURSES
- PDC_save_key_modifiers (TRUE);
- #endif
- crt_terminal_no_crt = FALSE;
- }
-
- void crt_done (void);
- void crt_done ()
- {
- if (!crt_inited || crt_ShutDown) return;
- if (crt_ActivePanel && !crt_terminal_no_crt)
- {
- DO_RETURN_ADDRESS (crt_update_immediately ());
- endwin ();
- }
- #ifdef USE_NCURSES
- if (crt_save_exit_ca_mode) tputs (crt_save_exit_ca_mode, 1, putch);
- crt_save_enter_ca_mode = crt_save_exit_ca_mode = NULL;
- #endif
- if (crt_save_previous_screen_flag > 0 && !crt_terminal_no_crt)
- crt_save_restore_screen (TRUE);
- crt_inited = 0;
- #ifdef XCURSES
- XCursesExit ();
- #endif
- }
-
- void crt_set_curses_mode (Boolean on);
- void crt_set_curses_mode (Boolean on)
- {
- if (!crt_inited || crt_ShutDown) return;
- if (on)
- {
- reset_prog_mode ();
- crt_rawout (TRUE);
- }
- else
- {
- crt_rawout (FALSE);
- reset_shell_mode ();
- }
- }
-
- void crt_delay (unsigned ms);
- void crt_delay (unsigned ms)
- {
- DO_CRT_CHECK_WINCHANGED;
- crt_update_immediately ();
- napms (ms);
- }
-
- static int get_ch (void)
- {
- int i;
- if (crt_ShutDown)
- return KEY_HUP;
- #ifdef XCURSES
- crt_ShutDownJumpActive = TRUE;
- if (setjmp (crt_ShutDownJump))
- i = KEY_HUP;
- else
- #endif
- /* Use stdscr rather than crt_ActivePanel -> w, so a non-top
- panel will not be redrawn. If the terminal is in non-CRT
- mode, use a dummy pad because a pad does *not* cause wgetch()
- to refresh(). Using the dummy pad in CRT mode does not work
- well for some reason (@@). */
- i = wgetch (crt_terminal_no_crt ? crt_dummy_pad : stdscr);
- #ifdef XCURSES
- crt_ShutDownJumpActive = FALSE;
- #endif
- return i;
- }
-
- static int wgetk ()
- {
- int i = get_ch ();
- if (i == KEY_RESIZE) crt_screen_size_changed = TRUE;
- if (crt_screen_size_changed)
- {
- DO_CRT_CHECK_WINCHANGED;
- if (i != KEY_RESIZE && i != ERR) crt_key_buf = i;
- if (crt_key_buf == KEY_RESIZE) crt_key_buf = 0;
- i = KEY_RESIZE;
- }
- return i;
- }
-
- void crt_select (void *PrivateData, Boolean *ReadSelect, Boolean *WriteSelect, Boolean *ExceptSelect);
- void crt_select (void *PrivateData, Boolean *ReadSelect, Boolean *WriteSelect, Boolean *ExceptSelect)
- {
- (void) PrivateData;
- DO_CRT_CHECK_WINCHANGED;
- if (*ReadSelect)
- {
- if (crt_update_level == UpdateRegularly)
- {
- crt_stop_refresh ();
- crt_refresh ();
- }
- (*ReadSelect) = !!(crt_unget_key_buf || crt_key_buf || crt_fkey_buf || crt_screen_size_changed);
- }
- if (crt_get_output_fd () >= 0) (*WriteSelect) = FALSE;
- (*ExceptSelect) = FALSE;
- }
-
- static Boolean crt_keypressed_internal ()
- {
- int ch;
- crt_nodelay (TRUE);
- ch = wgetk ();
- if (ch == ERR) return 0;
- crt_key_buf = ch;
- return 1;
- }
-
- Boolean crt_keypressed (void);
- Boolean crt_keypressed ()
- {
- DO_CRT_CHECK_WINCHANGED;
- if (crt_update_level >= UpdateInput) crt_update_immediately ();
- if (crt_unget_key_buf || crt_key_buf || crt_fkey_buf) return 1;
- return crt_keypressed_internal ();
- }
-
- void crt_SetScreenSize (int x, int y);
- void crt_SetScreenSize (int x, int y)
- {
- DO_CRT_CHECK_WINCHANGED;
- crt_update_immediately ();
- crt_change_screen_size (x, y);
- crt_screen_size_changed = TRUE;
- crt_setattr ();
- crt_redraw ();
- crt_GetLastMode ();
- crt_keypressed_internal ();
- if (crt_key_buf == KEY_RESIZE) crt_key_buf = 0;
- }
-
- void crt_SetMonochrome (Boolean Monochrome);
- void crt_SetMonochrome (Boolean Monochrome)
- {
- DO_CRT_CHECK_WINCHANGED;
- crt_ColorFlag = crt_HasColors && !Monochrome;
- crt_setattr ();
- crt_redraw ();
- crt_GetLastMode ();
- }
-
- void crt_ungetch (TKey ch);
- void crt_ungetch (TKey ch)
- {
- crt_unget_key_buf = ch;
- }
-
- static Char find_key (TKeyTable *table, int ch)
- {
- while (table -> curses_key != 0 && table -> curses_key != ch) table++;
- return table -> crt_key;
- }
-
- /* Don't use toupper() since it messes up the function key codes */
- static int upcase (int ch)
- {
- if (ch >= 'a' && ch <= 'z')
- return ch - 'a' + 'A';
- else
- return ch;
- }
-
- TKey crt_altkey (Char ch);
- TKey crt_altkey (Char ch)
- {
- return 0x100 * find_key (EscKeyTable, upcase (ch));
- }
-
- TKey crt_altgrkey (Char ch);
- TKey crt_altgrkey (Char ch)
- {
- return 0x100 * find_key (AltGrKeyTable, upcase (ch));
- }
-
- TKey crt_extrakey (Char ch);
- TKey crt_extrakey (Char ch)
- {
- return 0x100 * find_key (ExtraKeyTable, upcase (ch));
- }
-
- TKey crt_readkeyword (void);
- TKey crt_readkeyword ()
- {
- int ch, chu, shiftstate;
- Char c, cs;
- (void) &ch; /* don't put it into a register because of longjmp() */
- DO_CRT_CHECK_WINCHANGED;
- if (crt_update_level > UpdateWaitInput ||
- ((crt_update_level == UpdateWaitInput) &&
- !(crt_unget_key_buf || crt_key_buf || crt_keypressed_internal ())))
- crt_update_immediately ();
- if (crt_unget_key_buf)
- {
- TKey k = crt_unget_key_buf;
- crt_unget_key_buf = 0;
- return k;
- }
- else if (crt_key_buf)
- {
- ch = crt_key_buf;
- crt_key_buf = 0;
- if (ch == KEY_RESIZE)
- {
- int i;
- crt_nodelay (TRUE);
- i = get_ch ();
- if (i != KEY_RESIZE && i == ERR) crt_key_buf = i;
- }
- }
- else
- {
- crt_nodelay (FALSE);
- do
- {
- ch = wgetk ();
- if (crt_unget_key_buf) /* may have been set via crt_ungetch() by a handler for SIGINT etc. */
- {
- TKey k = crt_unget_key_buf;
- crt_unget_key_buf = 0;
- if (ch != ERR) crt_key_buf = ch;
- return k;
- }
- }
- while (ch == ERR);
- }
- if (ch == KEY_HUP)
- return 0x100 * ksHUp;
- #ifndef USE_PDCURSES
- if (ch == chEsc)
- {
- crt_nodelay (TRUE);
- ch = wgetk ();
- if (ch == ERR) return chEsc;
- c = find_key (EscKeyTable, upcase (ch));
- if (c != 0)
- return 0x100 * c;
- if (ch >= FKEY1 && ch <= FKEY1 + 9)
- return 0x100 * (ksAltF1 + ch - FKEY1);
- if (ch >= FKEY1 + 10 && ch <= FKEY1 + 11)
- return 0x100 * (ksAltF11 + ch - (FKEY1 + 10));
- crt_key_buf = ch;
- return chEsc;
- }
- #endif
- shiftstate = crt_getshiftstate ();
- if ((c = find_key (KeyTable, ch))) ch = c;
- chu = upcase (ch);
- if ((shiftstate & shShift) && (cs = find_key (ShiftKeyTable, chu))) return 0x100 * cs;
- if ((shiftstate & shAlt ) && (cs = find_key (AltKeyTable , chu))) return 0x100 * cs;
- if ((shiftstate & shAltGr) && (cs = find_key (AltGrKeyTable, chu))) return 0x100 * cs;
- if ((shiftstate & shExtra) && (cs = find_key (ExtraKeyTable, chu))) return 0x100 * cs;
- if (1 <= ch && ch <= 0xff) return ch;
- if (ch >= FKEY1 && ch <= FKEY1 + 9)
- {
- if (shiftstate & shAnyAlt)
- c = ksAltF1 + ch - FKEY1;
- else if (shiftstate & shCtrl)
- c = ksCtrlF1 + ch - FKEY1;
- else if (shiftstate & shShift)
- c = ksShF1 + ch - FKEY1;
- else
- c = ksF1 + ch - FKEY1;
- }
- else if (ch >= FKEY1 + 10 && ch <= FKEY1 + 11)
- {
- if (shiftstate & shAnyAlt)
- c = ksAltF11 + ch - (FKEY1 + 10);
- else if (shiftstate & shCtrl)
- c = ksCtrlF11 + ch - (FKEY1 + 10);
- else if (shiftstate & shShift)
- c = ksShF11 + ch - (FKEY1 + 10);
- else
- c = ksF11 + ch - (FKEY1 + 10);
- }
- else if (ch >= FKEYSH1 && ch <= FKEYSH1 + 9)
- c = ksShF1 + ch - FKEYSH1;
- else if (ch >= FKEYCTRL1 && ch <= FKEYCTRL1 + 9)
- c = ksCtrlF1 + ch - FKEYCTRL1;
- else if (ch >= FKEYALT1 && ch <= FKEYALT1 + 9)
- c = ksAltF1 + ch - FKEYALT1;
- else
- c = find_key (FKeyTable, ch);
- if ((shiftstate & shShift) && (cs = find_key (ShiftFKeyTable, c)))
- c = cs;
- else if ((shiftstate & shCtrl) && (cs = find_key (CtrlFKeyTable, c)))
- c = cs;
- else if ((shiftstate & shAlt) && (cs = find_key (AltFKeyTable, c)))
- c = cs;
- return 0x100 * c;
- }
-
- Char crt_readkey (void);
- Char crt_readkey ()
- {
- Char tmp;
- int ch;
- if (crt_fkey_buf)
- {
- tmp = crt_fkey_buf;
- crt_fkey_buf = 0;
- return tmp;
- }
- DO_RETURN_ADDRESS (ch = crt_readkeyword ());
- if (ch & 0xff) return ch;
- crt_fkey_buf= ch / 0x100;
- return 0;
- }
-
- size_t crt_winsize (void);
- size_t crt_winsize ()
- {
- DO_CRT_CHECK_WINCHANGED;
- return (crt_ActivePanel -> WindXMax - crt_ActivePanel -> WindXMin + 1)
- * (crt_ActivePanel -> WindYMax - crt_ActivePanel -> WindYMin + 1)
- * sizeof (chtype);
- }
-
- void crt_readwin (chtype *buf);
- void crt_readwin (chtype *buf)
- {
- DO_CRT_CHECK_WINCHANGED;
- {
- int xsize = crt_ActivePanel -> WindXMax - crt_ActivePanel -> WindXMin + 1,
- ysize = crt_ActivePanel -> WindYMax - crt_ActivePanel -> WindYMin + 1,
- yc, sx, sy;
- chtype temp [xsize + 1];
- getyx (crt_ActivePanel -> w, sy, sx);
- for (yc = 0; yc < ysize; yc++)
- {
- mvwinchnstr (crt_ActivePanel -> w, yc, 0, temp, xsize);
- memcpy (buf + xsize * yc, temp, xsize * sizeof (chtype)); /* don't copy the 0 terminator! */
- }
- wmove (crt_ActivePanel -> w, sy, sx);
- }
- }
-
- void crt_writewin (chtype *buf);
- void crt_writewin (chtype *buf)
- {
- DO_CRT_CHECK_WINCHANGED;
- {
- int xsize = crt_ActivePanel -> WindXMax - crt_ActivePanel -> WindXMin + 1,
- ysize = crt_ActivePanel -> WindYMax - crt_ActivePanel -> WindYMin + 1,
- yc, sx, sy;
- getyx (crt_ActivePanel -> w, sy, sx);
- for (yc = 0; yc < ysize; yc++)
- mvwaddchnstr (crt_ActivePanel -> w, yc, 0, buf + xsize * yc, xsize);
- wmove (crt_ActivePanel -> w, sy, sx);
- crt_need_refresh ();
- }
- }
-
- void crt_clrscr (void);
- void crt_clrscr ()
- {
- crt_setattr ();
- werase (crt_ActivePanel -> w);
- wmove (crt_ActivePanel -> w, 0, 0);
- crt_cursor_pos.x = crt_cursor_pos.y = 0;
- crt_need_refresh ();
- }
-
- void crt_clreol (void);
- void crt_clreol ()
- {
- crt_setattr ();
- wclrtoeol (crt_ActivePanel -> w);
- crt_need_refresh ();
- }
-
- void crt_insline (void);
- void crt_insline ()
- {
- crt_setattr ();
- winsertln (crt_ActivePanel -> w);
- (void) idlok (crt_ActivePanel -> w, TRUE);
- crt_need_refresh ();
- }
-
- void crt_delline (void);
- void crt_delline ()
- {
- crt_setattr ();
- wdeleteln (crt_ActivePanel -> w);
- (void) idlok (crt_ActivePanel -> w, TRUE);
- crt_need_refresh ();
- }
-
- void crt_setpccharset (Boolean PCCharSet);
- void crt_setpccharset (Boolean PCCharSet)
- {
- DO_CRT_CHECK_WINCHANGED;
- crt_ActivePanel -> PCCharSet = PCCharSet;
- }
-
- Boolean crt_getpccharset (void);
- Boolean crt_getpccharset ()
- {
- DO_CRT_CHECK_WINCHANGED;
- return crt_ActivePanel -> PCCharSet;
- }
-
- void crt_setcontrolchars (Boolean UseControlChars);
- void crt_setcontrolchars (Boolean UseControlChars)
- {
- DO_CRT_CHECK_WINCHANGED;
- crt_ActivePanel -> UseControlChars = UseControlChars;
- }
-
- Boolean crt_getcontrolchars (void);
- Boolean crt_getcontrolchars ()
- {
- DO_CRT_CHECK_WINCHANGED;
- return crt_ActivePanel -> UseControlChars;
- }
-
- size_t crt_read (void *PrivateData, Char *buffer, size_t size);
- size_t crt_read (void *PrivateData, Char *buffer, size_t size)
- {
- int res;
- size_t n;
- Char *p;
- (void) PrivateData;
- crt_setattr ();
- if (!crt_line_buf_count)
- {
- crt_nodelay (FALSE);
- crt_rawout (FALSE);
- echo ();
- if (crt_update_level >= UpdateWaitInput) crt_update_immediately ();
- do
- {
- errno = 0;
- res = wgetnstr (crt_ActivePanel -> w, crt_line_buf, MAXLENGTH - 1);
- }
- while
- #ifdef EINTR
- (res == ERR && errno == EINTR);
- #else
- (0);
- #endif
- if (res == ERR)
- crt_line_buf_count = 0;
- else
- {
- if (crt_CheckEOF)
- {
- do
- {
- p = strchr (crt_line_buf, 26);
- if (p) *p = 0;
- }
- while (p);
- }
- crt_line_buf_count = strlen (crt_line_buf);
- crt_line_buf [crt_line_buf_count++] = '\n';
- }
- crt_line_buf_pos = crt_line_buf;
- noecho ();
- crt_rawout (TRUE);
- }
- n = (crt_line_buf_count < size) ? crt_line_buf_count : size;
- memcpy (buffer, crt_line_buf_pos, n);
- crt_line_buf_pos += n;
- crt_line_buf_count -= n;
- return n;
- }
-
- void crt_flash (void);
- void crt_flash ()
- {
- DO_CRT_CHECK_WINCHANGED;
- flash ();
- }
-
- void crt_beep (void);
- void crt_beep ()
- {
- DO_CRT_CHECK_WINCHANGED;
- if (crt_VisualBell)
- crt_flash ();
- else
- {
- beep ();
- crt_delay (100);
- }
- }
-
- static chtype chtransform (Char ch, TTextAttr attr, Boolean PCCharSet)
- {
- Boolean pccs = PCCharSet || (ch < ' ');
- if (ch == 0
- #ifdef XCURSES
- || (crt_ColorFlag && (attr & 7) == ((attr >> 4) & 7))
- #endif
- || (attr & ~(crt_ColorFlag ? 0x80 : 0x88)) == 0)
- return ' ';
- #if !defined (USE_PDCURSES) || defined (XCURSES)
- if ((!crt_linux_console && pccs)
- || ch == chBell || ch == chBkSp || ch == chTab || ch == chLF || ch == chFF
- || ch == chCR || ch == chEsc || ch == 14 || ch == 15 || ch == 155)
- {
- if (ch < 32) return chars_0_31 [ch];
- if (ch >= 128)
- {
- chtype c = chars_128_255 [ch - 128];
- #ifdef XCURSES
- /* ACS_BLOCK is not supported in all charsets, but we can emulate it */
- if (c == ACS_BLOCK)
- c = ' ' | crt_attr2cursattr ((attr >> 4) | ((attr & 15) << 4));
- #endif
- return c;
- }
- }
- #endif
- if (!pccs && iscntrl (ch)) return ' ';
- return (crt_linux_console && pccs) ? ch | A_ALTCHARSET : ch;
- }
-
- void crt_readchar (int x, int y, Char *ch, TTextAttr *attr);
- void crt_readchar (int x, int y, Char *ch, TTextAttr *attr)
- {
- int sx, sy, cc;
- chtype c;
- crt_setattr ();
- getyx (crt_ActivePanel -> w, sy, sx);
- c = mvwinch (crt_ActivePanel -> w, y - 1, x - 1);
- *attr = cursattr2attr (c);
- c &= A_CHARTEXT;
- for (cc = 0x20; cc < 0x120 && (chtransform (cc % 0x100, 7, crt_ActivePanel -> PCCharSet) & A_CHARTEXT) != c; cc++);
- *ch = cc % 0x100;
- wmove (crt_ActivePanel -> w, sy, sx);
- }
-
- void crt_fillwin (Char ch, TTextAttr attr);
- void crt_fillwin (Char ch, TTextAttr attr)
- {
- DO_CRT_CHECK_WINCHANGED;
- wbkgdset (crt_ActivePanel -> w, crt_attr2cursattr (attr) | chtransform (ch, attr, crt_ActivePanel -> PCCharSet));
- werase (crt_ActivePanel -> w);
- crt_setattr ();
- crt_need_refresh ();
- }
-
- size_t crt_write (void *PrivateData, const Char *buffer, size_t size);
- size_t crt_write (void *PrivateData, const Char *buffer, size_t size)
- {
- size_t i;
- Char ch;
- (void) PrivateData;
- crt_setattr ();
- for (i = 0; i < size; i++)
- {
- ch = buffer [i];
- if (crt_ActivePanel -> UseControlChars)
- {
- if (ch == chBell)
- {
- crt_beep ();
- continue;
- }
- else if (ch == chBkSp)
- {
- int x, y;
- getyx (crt_ActivePanel -> w, y, x);
- if (x > 0)
- wmove (crt_ActivePanel -> w, y, x - 1);
- continue;
- }
- else if (ch == chLF)
- {
- int x, y;
- getyx (crt_ActivePanel -> w, y, x);
- if (y + crt_ActivePanel -> WindYMin >= crt_ActivePanel -> WindYMax)
- {
- if (crt_ActivePanel -> ScrollState) wscrl (crt_ActivePanel -> w, 1);
- wmove (crt_ActivePanel -> w, y, 0);
- }
- else
- wmove (crt_ActivePanel -> w, y + 1, 0);
- continue;
- }
- else if (ch == chCR)
- {
- int x, y;
- getyx (crt_ActivePanel -> w, y, x);
- wmove (crt_ActivePanel -> w, y, 0);
- continue;
- }
- }
- waddch (crt_ActivePanel -> w, chtransform (ch, crt_TextAttr, crt_ActivePanel -> PCCharSet));
- }
- update_crt_cursor_pos ();
- crt_need_refresh ();
- return size;
- }
-
- void crt_writecharattrat (int x, int y, int Count, TCharAttr *CharAttr);
- void crt_writecharattrat (int x, int y, int Count, TCharAttr *CharAttr)
- {
- crt_setattr ();
- {
- int m = crt_ActivePanel -> WindXMax - crt_ActivePanel -> WindXMin + 1 - x + 1;
- if (Count > m) Count = m;
- if (Count > 0)
- {
- chtype buf [Count];
- int cattr = 0, LastAttr = - 1, sx, sy, i;
- TTextAttr Attr;
- for (i = 0; i < Count; i++)
- {
- Attr = CharAttr [i].Attr;
- if (Attr != LastAttr)
- {
- cattr = crt_attr2cursattr (Attr);
- LastAttr = Attr;
- }
- buf [i] = chtransform (CharAttr [i].Ch, Attr, CharAttr [i].PCCharSet) | cattr;
- }
- getyx (crt_ActivePanel -> w, sy, sx);
- wmove (crt_ActivePanel -> w, y - 1, x - 1);
- crt_setscroll (FALSE);
- waddchnstr (crt_ActivePanel -> w, buf, Count);
- crt_setscroll (crt_ActivePanel -> ScrollState);
- wmove (crt_ActivePanel -> w, sy, sx);
- crt_need_refresh ();
- }
- }
- }
-